我正在尝试从c语言中调用java类的几个实例。代码在单个实例上运行良好,但是当我尝试调用多个java类的实例时就会失败。
有一个jar文件和一个用于java类的支持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没有什么好的想法。
发布于 2015-01-20 11:04:11
我认为你的意思不是“实例”,因为你正在调用一个静态方法,而是多个线程调用相同的静态方法?
如果是这样的话,您的第一次调用将会起作用,因为所使用的线程称为JNI_CreateJavaVM,它将成为您的java主线程。在创建JVM时,它会将当前的本机线程附加到JVM。
您所获得JNIEnv只对最初创建该JVM虚拟机的1个线程有效。如果您希望从其他本机线程调用相同的方法,则还需要使用JNI调用AttachCurrentThread附加这些线程。
请注意,每个线程都有一个不同的JNIEnv实例。
希望这能有所帮助。
PS:如果你正在向java方法传递一个简单的jint参数,我建议你使用CallStaticVoidMethod(env, DTK_ANPR_Test, dtk_anpr, 2)而不是不必要的分配内存来传递一个似乎永远不会释放的整数,所以这将是一个内存泄漏。
https://stackoverflow.com/questions/28018445
复制相似问题