Reputation: 6856
I'm an experienced Java coder, but I'm new to XCode and C++, so sorry for the dumb question.
I'm writing some c++ code in XCode that needs to instantiate a Java Virtual Machine. There is a method in the OS X Java plugin called JavaVM_GetJNIEnv(), and a header file in the source code from Sun/Oracle called JavaVM.h with these lines:
// Gets the JNIEnv* associated with the Java VM, creating the JVM
// instance if necessary. Note that the implementation of this routine
// must be prepared for it to be called from more than one thread.
JNIEnv* JavaVM_GetJNIEnv();
I added the .h file to my XCode project, but I don't know how to link to the binary file. I figured out how to force-load in the linker, like this:
-force_load /System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2_NPAPI.plugin/Contents/MacOS/JavaPlugin2_NPAPI
(this file is a symbolic link; the real path is /System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2_NPAPI.plugin/Contents/Resources/Java/libplugin2_npapi.jnilib)
But then I get this error message:
ld: in /System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2_NPAPI.plugin/Contents/MacOS/JavaPlugin2_NPAPI, can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)
collect2: ld returned 1 exit status
So my question is, how do I link to code in a .jnilib file with XCode?
Upvotes: 5
Views: 2214
Reputation: 6856
I figured it out. If you're trying to reference code stored in a .bundle, you don't actually link to it, you make calls to it at runtime and then reference the functions by name (ie. similar to Java's reflection, which I'm more familiar with).
NPError (*getEntryPoints)(NPPluginFuncs *aNPPFuncs); //Defines a variable which is a pointer to a function
CFURLRef bundleUrl = CFURLCreateWithFileSystemPath(NULL, CFSTR("/System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2_NPAPI.plugin"), kCFURLPOSIXPathStyle, true);
CFBundleRef bundleRef = CFBundleCreate(NULL, bundleUrl);
getEntryPoints = (NPError (*)(NPPluginFuncs *))CFBundleGetFunctionPointerForName ( bundleRef, CFSTR("NP_GetEntryPoints" ) ); //Sets the pointer function to a function loaded from the bundle
if( getEntryPoints == NULL ) {
printf("getEntryPoints is NULL");
} else {
NPPluginFuncs pluginFuncs;
pluginFuncs.size = sizeof(NPPluginFuncs);
NPError err = getEntryPoints( &pluginFuncs ); //This is what actually calls the library function
//... do more stuff with plugin API ...
}
As an aside, this didn't wind up being very useful for my purposes because as far as I can tell, the java plugin API is only designed to be called from Mozilla-based browsers, and I'm trying to embed Java in my own application.
Upvotes: 2
Reputation: 16986
You need to link to frameworks, not bundles. Choose 'Add Existing Framework' and select JavaVM.framework, and Xcode should handle the rest!
Upvotes: 2