Xcode中给出的Mach-O连接器错误: “_JNI_CreateJavaVM”,从引用:在main.o中
问题描述:
_main我得到这个错误从测试JNI:Xcode中给出的Mach-O连接器错误: “_JNI_CreateJavaVM”,从引用:在main.o中
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 /包括:JDK /包括/达尔文” 的项目,我也加上 “JDK/JRE/lib目录/服务器” 的库路径到该项目获取libjvm.dylib。我的项目的C++标准库的libstdC++(GNU C++标准库 但正如预期的我也解决不了这个问题
答
看看这里那里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)
现在,您的代码将使用版本tha你选择了。
我叉你的回购(recipeNo028),并成功地使用“make”命令。但程序recipeNo028_main需要Java SE6运行环境。不过,我已经安装了JDK8。我不知道为什么它需要Java SE6。我的教授还希望我使用6个以上的Java版本来研究JNI并解决一些问题。 –