我正在尝试从 C 语言调用 java 类的多个实例。该代码对于单个实例运行良好,但当我尝试调用 java 类的多个实例时会失败。
java类有一个jar文件和一个支持dll,并且java类被假定为一个完整的黑盒
JNIEnv* create_vm(JavaVM **jvm) {
JNIEnv *env;
JavaVMInitArgs vm_args;
JavaVMOption options[4];
options[0].optionString = "-Djava.compiler=none";
//Path to the java source code
options[1].optionString = "-Djava.class.path=G:\\dtk_testing\\dtk_test\\bin;C:\\Program Files (x86)\\DTK Software\\DTK ANPR SDK\\Bin\\Java\\DTKANPR.jar";
options[2].optionString = "-Djava.library.path=C:\\Windows\\System32";
//options[3].optionString = "-verbose";
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 4;
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_TRUE;
jint ret =JNI_CreateJavaVM(jvm, (void**)&env, &vm_args);
在 C 中使用以下方法调用类: 值 j 是我传递给 java 代码的参数,java 代码又调用具有该特定序列号的图像
void invoke_class(JNIEnv *env, char *str)
{
jclass DTK_ANPR_Test;
jmethodID dtk_anpr;
jint k=2;
jvalue *val=(jvalue *)malloc(sizeof(jvalue));
val->i=(jint *)malloc(sizeof(jint));
(val->i)=k;
DTK_ANPR_Test = (*env)->FindClass(env, "DTKANPRTest");
dtk_anpr = (*env)->GetStaticMethodID(env, DTK_ANPR_Test, "anpr", " (I)V");
(*env)->CallStaticVoidMethodA(env, DTK_ANPR_Test, dtk_anpr, val);
}
后来我在任何需要运行 java 类的地方调用这个方法“invoke_class”。
我认为并行运行代码(使用 openmp 或 mpi)就可以了,但我仍然不确定如何进一步进行
附注我对 openmp 或 mpi 没有任何好主意
最佳答案
我认为你的意思不是“实例”,因为你调用的是静态方法,而是多个线程调用同一个静态方法?
如果是这种情况,您的第一次调用将起作用,因为使用的线程名为 JNI_CreateJavaVM
这将成为你的java主线程。创建 JVM 时,它将当前 native 线程附加到 JVM。
JNIEnv
您得到的结果仅对最初创建 JVM 的 1 个线程有效。如果您想从其他 native 线程调用相同的方法,则还需要使用 JNI 调用 AttachCurrentThread
附加这些线程。 .
注意,您将拥有不同的 JNIEnv
每个线程的实例。
希望有帮助。
PS:如果您将简单的 jint 参数传递给 java 方法,我建议您使用 CallStaticVoidMethod(env, DTK_ANPR_Test, dtk_anpr, 2)
而不是不必要地分配内存来传递一个似乎永远不会被释放的整数,因此这将是内存泄漏。
关于java - 从 native C 代码调用 java 类的多个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28018445/