Been using the T7pro and LJM library to write a bunch of C++ code in Xcode with great success. All of these programs have been using the Command Line tool as the target with C++ being the language.
Although the command line tool is great, I'm needing to write the final package using a GUI for the end user on a Mac platform. I've tried using a bridging header with no sucesss. When using a bridging header, the project builds just fine but always crashes at run-time. I believe this is due to the way Cocoa is interacting with the LabJackM.dylib library.
Have you guys been able to use the LJM library in conjuction with a Cocoa app with either Swift or Objective-C?
Any help would be greatly appreciated.
Thanks Marc
What is the runtime error output? What is the stack trace when it crashes?
Which of the 3 following scenarios does it crash under?
1. LJM is imported and an LJM function is called
2. LJM is imported but no LJM function is called
3. LJM is not imported
We have not used LJM with Cocoa either Swift or Objective-C. This seems like the documentation for bridging headers:
https://developer.apple.com/documentation/swift/imported_c_and_objective...
It seems to be saying that bridging headers are for importing Objective-C into Swift. Does that mean you have created an Objective-C wrapper for LJM and you're trying to import that into a Swift project?
It looks like the LJM is imported and only crashes when I make a LJM function call. I've included the project so maybe you guys can help me sort this out.
I'm just trying to create a Objective-C project that will run using Xcode. Later if I can wrap this for Swift, then yes I'll give that a shot, but for now I'm just trying to take small steps in order to have something functioning with an easy to manage GUI using Xcode.
The project builds just fine on my computer but crashes during run time.
If I comment out the LJM_Open command in ViewController.m it will run just fine.
Thanks for takeing the time to look at this for me.
Marc
This is from the debug window
E0205 16:05:30.305708000 4295751104 server_chttp2.c:53] {"created":"@1549404330.305647000","description":"No address added out of total 1 resolved","file":"src/core/ext/transport/chttp2/server/chttp2_server.c","file_line":260,"referenced_errors":[{"created":"@1549404330.305643000","description":"Failed to add any wildcard listeners","file":"src/core/lib/iomgr/tcp_server_posix.c","file_line":353,"referenced_errors":[{"created":"@1549404330.305592000","description":"OS Error","errno":47,"file":"src/core/lib/iomgr/socket_utils_common_posix.c","file_line":271,"os_error":"Address family not supported by protocol family","syscall":"socket","target_address":"[::]:0"},{"created":"@1549404330.305643000","description":"Unable to configure socket","fd":4,"file":"src/core/lib/iomgr/tcp_server_utils_posix_common.c","file_line":215,"referenced_errors":[{"created":"@1549404330.305631000","description":"OS Error","errno":1,"file":"src/core/lib/iomgr/tcp_server_utils_posix_common.c","file_line":188,"os_error":"Operation not permitted","syscall":"bind"}]}]}]}
What happens if you call LJM_WriteLibraryConfigS("LJM_RPC_ENABLE", 0) before calling any other LJM calls?
Also, what version of LJM are you using?
Looks like it runs just fine when I call LJM_WriteLibraryConfigS("LJM_RPC_ENABLE", 0); before anything else
LJM_WriteLibraryConfigS("LJM_RPC_ENABLE", 0);
err = LJM_ReadLibraryConfigS(LJM_LIBRARY_VERSION, &Value);
printf("Value is %f\n", Value);
This prints "Value is 1.190"
Now after the above 3 lines of code, I add three more lines to test opening a device.
err = LJM_Open(LJM_dtANY, LJM_ctANY, "LJM_idANY", &handle);
ErrorCheck(err, "LJM_Open");
PrintDeviceInfoFromHandle(handle);
I get this error
LJM_Open error: "The error constants file '/usr/local/share/LabJack/LJM/ljm_constants.json' could not be opened." (ErrorCode: 1314)
Closing all devices and exiting now
I checked the ljm_constants.json file and it is located in the correct directory and all permissions are read and write.
Thanks
Marc
Does your Xcode project have some project-specific permissions on it? Does it run in some sort of sandbox? Is there a way to specify allow network permissions and file system permissions?
If you're able to use C++ code with LJM successfully, what's different about Objective C's environment?
Thanks for the reply. No project-specific permissions, or sandbox. Running Xcode on OS 10.14.2.
When using C++ in Xcode, I've always used the command line tool as the target. And have had no problems. For some reason, when using Cocoa as the target I can't get LJM to function.
Have you guys ever gotten LJM to run using Cocoa?
Not really sure what this line of code is doing? LJM_WriteLibraryConfigS("LJM_RPC_ENABLE", 0
It will compile and run with the last two lines of the folowing code commented out. That makes me think that it's not really opening the T7 even though the value of err after the LJM_Open call is 0; If I comment out the LJM_WriteLibraryConfig line, it crashes at the LJM_Open line.
LJM_WriteLibraryConfigS("LJM_RPC_ENABLE", 0);
err = LJM_ReadLibraryConfigS(LJM_LIBRARY_VERSION, &Value);
printf("Value is %f\n", Value);
err = LJM_Open(LJM_dtANY, LJM_ctANY, "LJM_idANY", &handle);
// ErrorCheck(err, "LJM_Open");
// PrintDeviceInfoFromHandle(handle);
Attached is the Xcode project file
Thanks Marc
LJM_RPC_ENABLE controls whether the current LJM instance opens a local port to listen for communications from other LJM instances:
https://labjack.com/support/software/api/ljm/constants/RPCConfigs
It's fine to disable LJM_RPC_ENABLE (by setting it to 0) because it's not used for device communication (just for LJM-to-LJM communication). The only situation where I think LJM_RPC_ENABLE would be important for you is if you wanted multiple instances of LJM sharing the same USB connection.
We have not previously tried to get LJM to work with Cocoa. I am not familiar with Objective C.
I notice that the two functions you've commented out are utility functions defined in LJM_Utilities.h. Is there something different about that file?
Please collect a log file. To do so, enable LJM debug logging via either of the two methods described here (Enabling via ljm_startup_configs.json or via LJM_WriteLibraryConfigS):
https://labjack.com/support/software/api/ljm/function-reference/debuggin...
Then close all LJM-related programs. After that, run your program as you have it in your last comment except with a 1 second sleep after LJM_Open. (LJM doesn't wait for the logger to exit before terminating and the logger periodically logs on a separate thread.)
Then, please post your /usr/local/lib/LabJack/LJM/ljm.log here.
Attached is the log file. Looks like it is not able to open file: /usr/local/share/LabJack/LJM/ljm_constants.json I checked and the file does indead exist in the correct directory. I checked the permissions on the file and they are set as Read & Write for all users. It doesn't look like this file is being called from any of the header files so my guess is that it is being called from one of the .dylibs.
It has to be some setting in the Cocoa Framework seeing that everything functions just fine when using C++.
Thanks for the help
Marc
Hey guys. I figured it out. Somehow, it was running in a sandbox. Changed the settings under entitlements and it it working.
Really appreciate the support you guys provide.
Marc
Glad to hear you got it working. Thanks for sharing the solution.
I started a page describing what permissions LJM needs in hopes that it might help the next person find the solution:
https://labjack.com/support/software/api/ljm/ljm-permissions