未定义的符号:Linux中的JNI_CreateJavaVM
undefined symbol: JNI_CreateJavaVM in Linux
我有两个项目。两者都是在Ubuntu 64位上的Netbeans IDE中创建的。
首先,我的.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
如何解决此问题?
我包含了我的.so项目的include路径。以下是我的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.o.d -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.o.d -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
它的编译和运行也非常好。
但问题是,当我试图创建Java虚拟机时,我收到了一条错误消息,"JNI_CreateJavaVM(&jvm,reinterpret_cast(&env),&vm_args)"。
以下是我所有的源代码,
for.so项目的testLib.h:
#ifndef TESTLIB_H
#define TESTLIB_H
class TestLib : public TestVir
{
public:
void init();
int createJVM();
};
#endif
for.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"), NULL },
{ 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 ;
}
您的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
相关文章:
- 通过JNI传递数据数组的最快方法是什么
- 为 NewObjectA() 函数创建 jvalues 的参数数组时出错 - JNI Invocation API
- 将 C# DLL 导入 C++ 以用于 JNI
- 用C++包装 Java 库 (JNI)
- 如何通过 JNI 将 C 字符串表情符号传递给 Java
- JNI从Android调用C++方法
- JVM 如何执行 JNI
- React Native (Android):无法通过 JNI 在 jobject 中返回字符串
- 如何将字符串数组返回到 java JNI
- JNI 日期值转换问题,在C++中获取不同的长整型值
- JNI,使用两个 .so 文件时出错,其中一个文件需要另一个文件
- Winapi - SetWindowLongPtr in ShutdownBlockReason创建/销毁JNI本机代码
- 将预编译的 C 共享库与 JNI/NDK 结合使用
- JNI 在应用程序中检测到错误:在为 innerclass 调用 NewObject 时使用了无效的 jobject
- 使用 jni 将返回带有模板的对象的 Java 代码转换为 c++
- 无法将DefineClass(JNI)与Qt资源一起使用
- 使用本机 JNI 静态方法实现C++ Java 运行时错误
- 从C++调用dll实现的JNI
- 如何在JNI中从线程内部调用JAVA方法
- 如何从 C/C++ 在 JNI for Java 中创建 UTF16 字符串?