【发布时间】:2015-02-24 19:43:23
【问题描述】:
我们有一个创建嵌入式 JVM 的本机 C++ 应用程序。此 JVM 中的类使用 SWIG 包装器回调到 C++ 对象方法(尽管使用 SWIG 并不重要;它可以很容易地成为从 javah 生成的本机函数存根)。例如,我们有一个带有本地方法的 Java 类,例如:
package net.foo;
public class CppWrapJNI {
public final static native long foo(
long l, Stuff jarg1_, String s
);
}
在 C++ DLL 中有相应的实现:
extern "C" {
__declspec(dllexport) jlong JNICALL
Java_net_foo_CppWrapJNI_1foo(
JNIEnv *jenv, jclass jcls,
jlong jarg1, jobject jarg1_, jstring jarg2
) {
return 1;
}
}
假设这个 DLL 被命名为“foo.dll”。
然后我们尝试让 JVM 通过 JNI 加载 DLL,使用如下代码:
jclass cls = env->FindClass("java/lang/System");
jmethodID mid = env->GetStaticMethodID(
cls, "loadLibrary", "(Ljava/lang/String;)V"
);
jstring jstr = env->NewStringUTF("foo.dll");
env->CallStaticVoidMethodV(cls, mid, jstr);
这一切正常,对 loadLibrary() 的调用没有报告错误(此处未显示 JNI 异常处理,但我们这样做了)。但是,稍后对 CppWrapJNI.foo() 的调用失败并出现如下错误:
java.lang.UnsatisfiedLinkError:
net.foo.CppWrapJNI.foo(JLnet/foo/Stuff;Ljava/lang/String;)J
奇怪的是,如果我纯粹用 Java 编写测试工具,以同样的方式调用 loadLibrary,一切正常。这很令人沮丧,因为我在网上看到的所有内容都表明这应该可以正常工作。
【问题讨论】: