我正在使用Java作为一个小应用程序。它是对现有MFC项目的重写。我需要更改现有的dll以使用JNI从Java启用访问。所有这些Java的东西对我来说都是新的,所以当我阅读其他论坛帖子时,我遇到了一些麻烦并且感觉相当密集。在现有的dll中我有这样的函数:
extern "C" __declspec(dllexport) bool Create()
{
return TRUE;
}
愚蠢的提问时间。如何正确设置它以供Java调用?
我试过了:
JNIEXPORT jboolean JNICALL Create()
{
return TRUE;
}
我包括jni.h,一切都很好。但是,当我从Java调用它时,我得到UnsatisfiedLinkError。我用Java来调用它:
public static native boolean CreateSession();
System.load("D:\\JavaCallTest.dll");
Create();
有人可以向我推进正确的方向吗?我衷心感谢任何帮助。
谢谢,
尼克
答案 0 :(得分:7)
您需要在本机代码中包含Java类名称和路径,例如,如果您的本机方法在Java中声明为:
public class NativeCode {
public static native boolean CreateSession();
}
并且类路径是(例如)com.example.NativeCode
您将在本机中声明您的方法,如下所示:
extern "C"
JNIEXPORT jboolean JNICALL Java_com_example_NativeCode_CreateSession(JniEnv* env, jclass clazz)
{
return JNI_TRUE;
}
所有JNI方法都有一个JNIEnv指针和类作为它们的前两个参数。
答案 1 :(得分:2)
静态本机方法仍然至少需要两个参数:
JNIEnv *env
jclass clazz
函数名也必须与java包结构相对应。
JNIEXPORT jboolean JNICALL Java_com_example_CreateSession(JNIEnv *env, jclass clazz)
理想情况下,您可以使用javah
工具从java类创建头文件,声明本机方法,然后实现声明的函数原型。
答案 2 :(得分:1)
我遇到了类似的问题 - 我需要从Java访问的现有C代码库。它为我付出了代价,熟悉SWIG,一个生成中间C ++ DLL(调用C代码)的工具,以及调用C ++ DLL的Java代码。
如果你有不止一个DLL函数来包装,那么查看这个工具可能会有所收获,否则你必须熟悉JNI ......
修改强>:
似乎System.load()
调用找不到您的DLL。您可能想尝试System.loadLibrary()
,但请注意,您的DLL必须位于Java系统属性java.library.path
表示的路径中。
在这种情况下也不要传递完整的文件名,而只是没有扩展名的文件名。