Xcode给出了Mach-O链接器错误:“_ JNI_CreateJavaVM”,引自:main.o中的_main

时间:2017-10-20 11:35:10

标签: c++ xcode java-native-interface

我从测试JNI得到了这个错误:

Undefined symbols for architecture x86_64:
  "_JNI_CreateJavaVM", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这是c ++代码:

    #include <jni.h>
    #include <iostream>
    using namespace std;
    int main()
    {
        int res;
        JavaVMInitArgs vm_args;
        JavaVMOption options[3];
        JavaVM *jvm;
        JNIEnv *env;
        jmethodID mid;

        options[0].optionString = "-Djava.compiler=NONE";

        options[1].optionString = "-Djava.class.path = /Users/stephen/course/test/Test";
        options[2].optionString = "-verbose:NONE";

        vm_args.version = JNI_VERSION_1_8;
        vm_args.nOptions = 3;
        vm_args.options = options;
        vm_args.ignoreUnrecognized = JNI_TRUE;

       res = JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args);
       if(res == JNI_ERR){
           cout << "Error invoking the JVM";
           return 1;
       }
       cout <<"create JVM successfully!"<<endl;
       jclass cls = env->FindClass("/Users/stephen/course/Qt-project/test/Test");
       if(cls != 0){
           cout<<"find class successfully!" << endl;
       }
        mid = env->GetMethodID(cls,"sayHello","stephen");
        if(mid != 0){
            cout<<"Invoke method successfully!" << endl;
        }
        jvm->DestroyJavaVM();
        return 0;

    }

这是java代码:

public class Test
{
    public static void sayHello(String s){
        System.out.print("hello I am" + s + "\n");
    }

}

我添加了“jdk / include; jdk / include / darwin”项目的include路径,我还将“jdk / jre / lib / server”的lib路径添加到项目中以获取libjvm.dylib。我项目的c ++标准库是libstdc ++(gnu c ++标准库。 但我无法按预期解决这个问题。

1 个答案:

答案 0 :(得分:0)

在这里查看一个示例代码,其中JVM库与您的项目链接:

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo028

看看Makefile。特别是,在这里:

main: recipeNo028_main.o
    ld -o lib/recipeNo028_main -L${JAVA_HOME}/jre/lib/server/ \
    -ljvm \
        $(MAC_OS_FLAGS) \
    lib/recipeNo028_main.o

其中jvm lib与代码链接,在这里:

CC=llvm-gcc
MAC_OS_FLAGS=-rpath ${JAVA_HOME}/jre/lib/server -L/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -demangle -dynamic -arch x86_64 -macosx_version_min 10.12.0 -lSystem

其中所有必需的库也添加到您的代码中。它应该工作。尝试编译示例代码。您可以在此处找到更多示例:http://jnicookbook.owsiak.org

<强>更新

如何使用任意JDK版本进行编译。

首先,看看你有的所有装置

/usr/libexec/java_home -V

这会产生类似这样的东西

/usr/libexec/java_home -V
Matching Java Virtual Machines (4):
    9, x86_64:  "Java SE 9" /Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home
    1.8.0_144, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home
    1.8.0_111, x86_64:  "Java SE 8" /Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home
    1.7.0_80, x86_64:   "Java SE 7" /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home

然后,在运行make之前,只需将JAVA_HOME设置为您喜欢的任何内容

export JAVA_HOME=$(/usr/libexec/java_home -v 9)

现在,您的代码将使用您选择的版本。