您好我正在编写一个c ++代码来从.jar类调用java函数。
这是:
#include <jni.h>
int main()
{
JavaVMOption options[1];
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
long status;
jclass JCTerminalClass;
jmethodID mid;
jobject obj;
char op0[] = "-Djava.class.path=C:\\Users\\DMNX1594\\Downloads\\jcop\\jcop/offcard.jar";
options[0].optionString =op0;
vm_args.version = JNI_VERSION_1_6;
vm_args.nOptions = 1;
vm_args.options = options;
status = JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
if (status != JNI_ERR)
{
JCTerminalClass = env->FindClass("JCTerminal");
jthrowable exc;
exc = env->ExceptionOccurred();
if (exc)
{
jclass newExcCls;
env->ExceptionDescribe();
env->ExceptionClear();
}
if(JCTerminalClass !=0)
{
mid = env->GetMethodID(JCTerminalClass, "com.ibm.jc.JCTerminal()", "()V");
// Call here instance function later ...
}
.
.
.
jvm->DestroyJavaVM();
return 0;
} else
return -1;
}
编译顺利,但在执行期间,我得到以下内容:
java.lang.NoClassDefFoundError:JCTerminal 引起:java.lang.ClassNotFoundException:java.net.URLClassLoader $ 1.run(URLClassLoader.java:372)中的JCTerminal,java.net.URLClassLoader $ 1.run(URLClassLoader.java:361),java.security.AccessController.doPrivileged (原生方法) 在java.net.URLClassLoader.findClass(URLClassLoader.java:360) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher $ AppClassLoader.loadClass(Launcher.java:308) 在java.lang.ClassLoader.loadClass(ClassLoader.java:357)
我已经尝试从我创建的.jar中调用简单的静态java函数并且它有效! 代码类似于这个代码。
我尝试将CLASSPATH环境变量设置为C:\ path \ to \ jarFile \ offcard.jar,因为我读到在编译期间找到类但在执行期间找不到类时会发生NoClassDefFoundError ...
可能是线程问题?
哦,这是我的编译命令: g ++ -D __int64 =“long long”-I“C:\ Program Files \ Java \ jdk1.8.0_05 \ include”-I“C:\ Program Files \ Java \ jdk1.8.0_05 \ include \ win32”-L“ C:\ Program Files \ Java \ jdk1.8.0_05 \ jre \ bin \ server“-L”C:\ Program Files \ Java \ jdk1.8.0_05 \ lib“-o jni jni.cpp -ljvm
谢谢stackoverflowers:)
答案 0 :(得分:1)
您的代码似乎在JCTerminalClass = env->FindClass("JCTerminal");
JNIEnv-&gt; FindClass的文档说明了这一点:
jclass FindClass(JNIEnv *env, const char *name);
[...]
name参数是完全限定的类名或数组类型 签名。例如,完全限定的类名
java.lang.String
类是:"java/lang/String"
但是,您只是传递字符串"JCTerminal"
而没有任何包名称。稍后在您的示例中,您将在类名称前显示包名称:"com.ibm.jc.JCTerminal()"
但是在JNI代码中,包名称分隔符不是点(。)而是斜杠(/),如上面的文档中所示。所以你需要传递给FindClass方法的是"com/ibm/jc/JCTerminal"
:
JCTerminalClass = env->FindClass("com/ibm/jc/JCTerminal");