【问题标题】:Need help linking to bundle on OS X需要帮助链接到 OS X 上的捆绑包
【发布时间】:2011-07-11 19:42:06
【问题描述】:

我是一名经验丰富的 Java 编码员,但我是 XCode 和 C++ 的新手,很抱歉这个愚蠢的问题。

我正在用 XCode 编写一些需要实例化 Java 虚拟机的 c++ 代码。 OS X Java 插件中有一个名为 JavaVM_GetJNIEnv() 的方法,Sun/Oracle 的源代码中有一个名为 JavaVM.h 的头文件,其中包含以下几行:

// 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();

我将 .h 文件添加到我的 XCode 项目中,但我不知道如何链接到二进制文件。我想出了如何在链接器中强制加载,如下所示:

-force_load /System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2_NPAPI.plugin/Contents/MacOS/JavaPlugin2_NPAPI

(此文件为符号链接;真实路径为/System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2_NPAPI.plugin/Contents/Resources/Java/libplugin2_npapi.jnilib)

但随后我收到此错误消息:

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

所以我的问题是,如何使用 XCode 链接到 .jnilib 文件中的代码?

【问题讨论】:

    标签: xcode cocoa macos linker bundle


    【解决方案1】:

    您需要链接到框架,而不是捆绑包。选择“Add Existing Framework”并选择 JavaVM.framework,剩下的由 Xcode 处理!

    【讨论】:

    • 我的框架列表中已经有 JavaVM.framework ......也许该函数是在不同的库中定义的。我将使用“nm”进行一些搜索,以尝试准确找出哪个二进制文件具有我正在寻找的功能;也许我只需要添加一个不同的框架。
    • 好的,我找到了文件的真实位置。我使用“nm”来验证是否包含了我需要的功能。实际二进制文件的位置是“/System/Library/Java/Support/Deploy.bundle/Contents/Resources/JavaPlugin2_NPAPI.plugin/Contents/MacOS/JavaPlugin2_NPAPI”。由于我无法将捆绑包添加到 XCode,我将如何链接到这个?
    • 在 osx 下,gcc 包装器接受 -F 和 -framework 作为参数。 -F/-framework 类似地等同于 -L/-l,但我认为 sbooth 是正确的 - 如果它没有正确链接,那么有些东西是不稳定的。
    • 您尝试链接的内容是 Web 浏览器的 Java 插件的一部分(因此路径中有 NPAPI)。你确定这就是你想要的吗?
    【解决方案2】:

    我想通了。如果您尝试引用存储在 .bundle 中的代码,则实际上并没有链接到它,而是在运行时调用它,然后按名称引用函数(即类似于 Java 的反射,我更喜欢熟悉)。

    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 ...
    }
    

    顺便说一句,这对我的目的并不是很有用,因为据我所知,java 插件 API 仅设计为从基于 Mozilla 的浏览器调用,我正在尝试嵌入我自己的应用程序中的 Java。

    【讨论】:

      猜你喜欢
      • 2011-12-19
      • 1970-01-01
      • 2020-06-26
      • 1970-01-01
      • 1970-01-01
      • 2012-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多