首页 > 解决方案 > 动态加载 jvm.dll 而不链接它

问题描述

所以,最近我一直在考虑通过 C/C++ 调用 Java 方法,但是一个很大的问题是必须将 jvm.dll 添加到路径中,我一直在想如果我找到了 jvm 就不可能了。 dll 通过获取 JAVA_HOME 并在 Linux/MacOS 的情况下放置“\bin\server”或“/bin/server”,然后我会找到它,例如在 Windows 上使用 Windows.h 中的 LoadLibrary 来加载函数并使其工作没有链接任何东西?我可以考虑这种可能性,但我找不到我需要的工具,例如我应该加载哪个方法,它有什么参数,它返回什么?ETC

标签: c++cjava-native-interface

解决方案


您只需要使用JNI_CreateJavaVM创建一个 JVM,然后从那里,您通常会得到一个函数指针结构,因此您只需要使用dlsym某些函数。我使用了这些dl*功能,但是在带有LoadLibraryand的 windows 上它是完全一样的GetProcAddress

#include <jni.h> //For the typedefs, struct definitions,...
....
typedef jint (*createJVMFuncPointer_t)(JavaVM **p_vm, void **p_env, void *vm_arg);
....
//I ommitted all checks for errors.
void* handleToLibJVM=dlopen(yourPathToJvmDllOrSo,RTLD_LAZY);
createJVMFuncPointer_t createJVM=(createJVMFuncPointer_t)dlsym(handleToLibJVM,"JNI_CreateJavaVM");
JavaVM *jvm;
JNIEnv *env;
JavaVMOption* options = ...;
//TODO: Initialize options (For things like the classpath and other options)
jint errorCode=createJVM(&jvm, (void**)&env, &vm_args);
//From here you can start looking for your methods written in Java.
jclass cls=(*env)->FindClass(env,"foo/bar/SomeClass");
//Search for method in this class with name baz, taking two ints and returning void.
jmethodID mid=(*env)->GetStaticMethodID(env,cls,"baz","(II)V");
(*env)->CallStaticVoidMethod(env,cls,mid,1,2);
//TODO: Cleanup`(dlclose, free, DestroyJavaVM)

推荐阅读