我有一个测试用例,我试图使用JNI从我的Java程序访问C代码。涉及的步骤如下:
1。调用本机方法的Java程序:
public class RunnerClass{
public native void win32_svc_install();
static{
System.loadLibrary("testDll");
System.out.println("library loaded successfully");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new RunnerClass().win32_svc_install();
}
}
2。现在生成.class
文件并从创建的相应.h
文件生成后,我在.c
文件中放置了本机方法实现。
/* DO NOT EDIT THIS FILE - it is machine generated */
//RunnerClass.h
#include <jni.h>
/* Header for class RunnerClass */
#ifndef _Included_RunnerClass
#define _Included_RunnerClass
#ifdef __cplusplus
extern "C" {
#endif/*
* Class: RunnerClass
* Method: nx_win32_svc_install
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_RunnerClass_win32_1svc_1install
(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif
RunnerClass.c
文件具有其中的本机方法的实现。这个方法究竟要做的是调用窗口的ServiceManager
来使用它。我的Java程序需要执行这些操作。
现在问题出现在创建testDll.dll
之后。在解释Java代码之前,我在testDll
中设置了所需库(java.library.path
)的库路径。
现在当我运行我的程序时,我的库被加载但它会将UnsatisfiedLinkError
抛出到本机方法。确切的错误如下:
Exception in thread "main" hello ,java.lang.UnsatisfiedLinkError: RunnerClass.win32_svc_install(ILjava/lang/String;)V
at RunnerClass.win32_svc_install(Native Method)
at RunnerClass.main(MainWs.java:58)
我做了很多研究,并且到目前为止已经理解异常被抛出,因为程序无法在被加载的库中找到本机方法的实现。
答案 0 :(得分:1)
异常确实与您的代码不匹配。 在Java中,您将该函数声明为
public native void win32_svc_install();
在c ++中,将函数声明为
JNIEXPORT void JNICALL Java_RunnerClass_win32_1svc_1install (JNIEnv *, jobject);
我认为它应该被声明为
JNIEXPORT void JNICALL Java_RunnerClass_win32_svc_install (JNIEnv *, jobject);
但除了c ++声明中的奇怪“1”之外,似乎还有另一个问题。 这两个函数都被正确地声明为零参数的void函数。
但是你的异常表明它正在寻找一个同名的void函数,但是带有一个整数和一个字符串参数:
RunnerClass.win32_svc_install(ILjava/lang/String;)V
在查看代码时,我无法想象为什么。我尝试通过重命名我的一个C ++函数来重现它;以下未满足的链接异常正确地说明了已定义的参数。