我有2个项目。 两者都是在Ubuntu 64位的Netbeans IDE中创build的。
首先,我的.so项目实现了从c ++代码调用Java函数。 和我的控制台应用程序尝试调用.so文件中的函数。
编译和运行时出现如下错误:
/home/online0227/desktop/jvm run/dist/DeBUG/GNU-linux-x86/jvm_run: symbol lookup error: ./libjvm_dll.so: undefined symbol: JNI_CreateJavaVM
如何解决这个问题?
在linux中将共享库链接到另一个共享库
是否可以使用windows和linux的客户端使用相同的DLL
linux上的Java System.loadlibrary调用冻结
有没有一种方法可以确定linux上库的线程本地存储模型
如何检查运行时为给定进程加载哪些共享库?
我包括了我的.so项目的path。 这是我编译.so项目时,netbeans在其编译输出上显示的内容:
g++ -c -g -I/home/online0227/jdk1.7.0_25_x64/include/linux -I/home/online0227/jdk1.7.0_25_x64/include -fPIC -MMD -MP -MF build/DeBUG/GNU-linux-x86/_ext/1117207477/testlib.od -o build/DeBUG/GNU-linux-x86/_ext/1117207477/testlib.o /home/online0227/desktop/jvm dll/testlib.cpp g++ -o dist/DeBUG/GNU-linux-x86/libjvm_dll.so build/DeBUG/GNU-linux-x86/_ext/1117207477/testlib.o -shared -fPIC
这个.so编译得很好,生成.so文件。
以下是我的Netbeans在编译我的主控制台应用程序时显示的内容:
g++ -c -g -I/home/online0227/jdk1.7.0_25_x64/include/linux -I/home/online0227/jdk1.7.0_25_x64/include -MMD -MP -MF build/DeBUG/GNU-linux-x86/main.od -o build/DeBUG/GNU-linux-x86/main.o main.cpp g++ -o dist/DeBUG/GNU-linux-x86/jvm_run build/DeBUG/GNU-linux-x86/main.o -L/home/online0227/jdk1.7.0_25_x64/jre/lib/amd64/server -ldl -ljvm
它也编译得很好,运行。
但问题是,当我尝试创buildJava虚拟机“JNI_CreateJavaVM(&jvm,reinterpret_cast(&env),&vm_args)”时出现错误消息。
以下是我所有的源代码,
.so项目的testlib.h :
#ifndef TESTliB_H #define TESTliB_H class Testlib : public TestVir { public: voID init(); int createJVM(); }; #endif
.so项目的testVir.h :
#ifndef TESTVIR H #define TESTVIR_H class TestVir { public: virtual voID init()=0; virtual int createJVM()=0; }; #endif
.so项目的testlib.cpp :
#include <iostream> #include <jni.h> #include <cassert> #include "testVir.h" #include "testlib.h" using namespace std; voID Testlib::init() { cout<<"Testlib::init: Hello World!! "<<endl ; } int Testlib::createJVM() { const int kNumOptions = 3; JavaVMOption options[kNumOptions] = { { const_cast<char*>("-Xmx128m"),NulL },{ const_cast<char*>("-verbose:gc"),{ const_cast<char*>("-Djava.class.path=."),NulL } }; JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_6; vm_args.options = options; vm_args.noptions = sizeof(options) / sizeof(JavaVMOption); assert(vm_args.noptions == kNumOptions); jnienv* env = NulL; JavaVM* jvm = NulL; int res = JNI_CreateJavaVM(&jvm,reinterpret_cast<voID**>(&env),&vm_args); if (res != JNI_OK) { std::cerr << "Failed: JNI_CreateJavaVM " << res << std::endl; return -1; } jclass cls; jmethodID mID; jobject obj; int staticresult = 0; int result = 0; long status; if (status != JNI_ERR) { cls = env->FindClass("PWNJavaGUI"); if (cls != 0) { mID = env->GetStaticmethodID(cls,"main","([Ljava/lang/String;)V"); if (mID != 0) { env->CallStaticVoIDMethod(cls,mID); mID = env->GetStaticmethodID(cls,"isPass","()Z"); // public static int returnCheckBox() if (mID != 0) { while (env->CallStaticBooleanMethod(cls,mID) == 0) { // Do nothing but just wait until the user select game start button // } } else { // Log("Error : env->GetStaticmethodID for isLoop"); return 0; } } else { // Log("Error : env->GetStaticmethodID for main"); return 0; } } else { // Log("Error : env->FindClass"); return 0; } } return 1; jvm->DestroyJavaVM(); return 0; } //define functions with C symbols (create/destroy Testlib instance). extern "C" Testlib* create() { return new Testlib; } extern "C" voID destroy(Testlib* Tl) { delete Tl ; }
最后,这是我的主要控制台应用程序main.cpp :
#include<iostream> #include <stdio.h> #include<dlfcn.h> #include "testVir.h" using namespace std; int main() { voID *handle; handle = dlopen("./libjvm_dll.so",RTLD_LAZY); if (!handle) { printf("The error is %s",dlerror()); } typedef TestVir* create_t(); typedef voID destroy_t(TestVir*); create_t* creat=(create_t*)dlsym(handle,"create"); destroy_t* destroy=(destroy_t*)dlsym(handle,"destroy"); if (!creat) { cout<<"The error is %s"<<dlerror(); } if (!destroy) { cout<<"The error is %s"<<dlerror(); } TestVir* tst = creat(); tst->init(); tst->createJVM(); destroy(tst); return 0 ; }
为什么-O去gcc导致“stat”解决?
dynamic加载静态库?
将dlopen产生相同的文件处理两个电话相同的处理?
windows上的主要Vs. __attribute __((构造函数))入口点在linux上
运行独立共享库时,gdb不加载符号
你的libjvm_dll.so使用来自libjvm.so的符号,所以当你构建它时,它应该被链接到它。
g++ -o dist/DeBUG/GNU-linux-x86/libjvm_dll.so build/DeBUG/GNU-linux-x86/_ext/1117207477/testlib.o -shared -fPIC -L/home/online0227/jdk1.7.0_25_x64/jre/lib/amd64/server -ljvm
整个构建过程:
# Build libjvm_dll.so g++ -o libjvm_dll.so -I $JAVA_HOME/include testlib.cpp -shared -fPIC -L $JAVA_HOME/jre/lib/amd64/server -ljvm # Build main executable g++ -o jvm_run main.cpp -ldl # Run LD_liBRARY_PATH=$JAVA_HOME/jre/lib/amd64/server ./jvm_run
尝试看看这个网站的博客
https://forums.oracle.com/thread/1551216
总结以上是内存溢出为你收集整理的未定义的符号:在Linux中的JNI_CreateJavaVM全部内容,希望文章能够帮你解决未定义的符号:在Linux中的JNI_CreateJavaVM所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)