C++ 如何在linux中从静态加载的库中执行函数?

C++ 如何在linux中从静态加载的库中执行函数?,c++,c,static-linking,C++,C,Static Linking,我正在用linux为java程序编写一个本机启动器。启动器应该静态加载libjvm.so并通过函数指针执行函数JNI\u CreateJavaVM(),这样我就可以启动可执行文件,而无需首先设置LD\u LIBRARY\u路径 到目前为止,我已经知道了如何编译和链接它,但我正在努力解决声明函数指针然后稍后执行函数的语法问题: JavaVM *jvm; JNIEnv *env; JavaVMInitArgs vm_args; JavaVMOption* options = new JavaVMOp

我正在用linux为java程序编写一个本机启动器。启动器应该静态加载libjvm.so并通过函数指针执行函数
JNI\u CreateJavaVM()
,这样我就可以启动可执行文件,而无需首先设置
LD\u LIBRARY\u路径

到目前为止,我已经知道了如何编译和链接它,但我正在努力解决声明函数指针然后稍后执行函数的语法问题:

JavaVM *jvm;
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption* options = new JavaVMOption[10];

...

std::string location = "./jre/lib/server/libjvm.so";
void *handle = dlopen ( location.c_str(), RTLD_LAZY );

if ( !handle ) {
   printf ( "Unable to load %s, exiting", location.c_str() );
   return 0;
}

?? = dlsym ( handle, "JNI_CreateJavaVM" ); //get the function pointer

//This is how I would execute the function if dynamically linking: 
//JNI_CreateJavaVM( &jvm, (void**)&env, &vm_args );

?? ( &jvm, (void**)&env, &vm_args ); //Execute the function pointer. 
我应该用什么神奇的词语来代替
来实现这一点?我已经尝试过使用C/C++了,但我对C/C++太不熟悉,无法将其转换为我的情况

谢谢

首先,为要检索的函数声明一个类型(此处为
p\u JNI\u CreateJavaVM
):

typedef jint (*p_JNI_CreateJavaVM)(JavaVM**, void**, void**);
p_JNI_CreateJavaVM JNI_CreateJavaVM = (p_JNI_CreateJavaVM)dlsym(handle, "JNI_CreateJavaVM");
您可以像往常一样调用它:

jint ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
首先,为要检索的函数声明一个类型(此处为
p_JNI_CreateJavaVM
):

typedef jint (*p_JNI_CreateJavaVM)(JavaVM**, void**, void**);
p_JNI_CreateJavaVM JNI_CreateJavaVM = (p_JNI_CreateJavaVM)dlsym(handle, "JNI_CreateJavaVM");
您可以像往常一样调用它:

jint ret = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

您是否看到
dlopen
手册页中的示例?还有,
JNI
没有涵盖这一点吗?另外,这是动态加载/链接,而不是“静态的”。JNI介绍了这一点,但是Oracle提供的示例没有提供这种形式的示例——它们需要jvm.dll/libjvm.so,所以在执行之前必须在path中。我根本不是C/C++的人,所以我不懂行话,也不熟悉语法,但我知道这是我需要的解决方案的基本形式。我让它在windows下工作,但我不能在Linux上完全正确地理解语法。为什么你不想
dlopen
libjvm.so而不正常地链接到它
dlopen
通常用于插件。如果问题是ibjvm.so不在您的默认库路径中,您可以通过设置
LD_library_path
来解决此问题。您是否看到
dlopen
手册页中的示例?还有,
JNI
没有涵盖这一点吗?另外,这是动态加载/链接,而不是“静态的”。JNI介绍了这一点,但是Oracle提供的示例没有提供这种形式的示例——它们需要jvm.dll/libjvm.so,所以在执行之前必须在path中。我根本不是C/C++的人,所以我不懂行话,也不熟悉语法,但我知道这是我需要的解决方案的基本形式。我让它在windows下工作,但我不能在Linux上完全正确地理解语法。为什么你不想
dlopen
libjvm.so而不正常地链接到它
dlopen
通常用于插件。如果问题是ibjvm.so不在默认库路径中,您可以通过设置
LD_library_path
I必须更改typedef以使其编译:
typedef jint(*p_JNI_CreateJavaVM)(JavaVM**,void**,JavaVMInitArgs*)否则这就行了。非常感谢。我正要把它列为
void**
我对C/C++的了解还不够透彻。编译器告诉我
launch.cpp:In函数'int main(int,char**)':launch.cpp:51:60:错误:无法在传递jint ret=JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args)的参数中将'JavaVMInitArgs*'转换为'void**'所以我尝试将最后一个参数改为
JavaVMInitArgs*
,效果很好。@JoshuaD JNI规范从技术上讲是为C编写的,C允许在不使用强制转换的情况下转换为/from
void*
。C++需要一个显式的强制转换。因为我好奇,如果你有C++ 14的访问权限,你可以做<代码> TyPulfDeCype(& JNIOCREATEJAVAVM)PyjnIIIKCREATEJAVAVM;代码>在不输入(或思考)的情况下获取类型。我必须更改typedef以使其编译:
typedef jint(*p_JNI_CreateJavaVM)(JavaVM**,void**,JavaVMInitArgs*)否则这就行了。非常感谢。我正要把它列为
void**
我对C/C++的了解还不够透彻。编译器告诉我
launch.cpp:In函数'int main(int,char**)':launch.cpp:51:60:错误:无法在传递jint ret=JNI_CreateJavaVM(&jvm,(void**)&env,&vm_args)的参数中将'JavaVMInitArgs*'转换为'void**'所以我尝试将最后一个参数改为
JavaVMInitArgs*
,效果很好。@JoshuaD JNI规范从技术上讲是为C编写的,C允许在不使用强制转换的情况下转换为/from
void*
。C++需要一个显式的强制转换。因为我好奇,如果你有C++ 14的访问权限,你可以做<代码> TyPulfDeCype(& JNIOCREATEJAVAVM)PyjnIIIKCREATEJAVAVM;代码>无需输入(或思考)即可获取类型。