【问题标题】:Exception in thread "main" java.lang.UnsatisfiedLinkError: RunnerClass.parsecmdline(ILjava/lang/String;)V线程“主”java.lang.UnsatisfiedLinkError 中的异常:RunnerClass.parsecmdline(ILjava/lang/String;)V
【发布时间】:2013-03-16 12:58:34
【问题描述】:

我有一个测试用例,我尝试使用 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 文件中包含本地方法的实现。这个方法究竟要做的是调用windows的ServiceManager来使用它。我的 Java 程序需要执行这些操作。

现在问题出现在testDll.dll 创建之后。在解释 Java 代码之前,我在java.library.path 中设置了所需库(testDll)的库路径。

现在,当我运行我的程序时,我的库被加载,但它会将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)

我做了很多研究,到目前为止,我了解到抛出异常是因为程序无法在正在加载的库中找到本机方法的实现。

【问题讨论】:

  • parsecmdline()的功能是什么?
  • 本地方法好像在尝试调用Java方法,找不到Java方法。你有原生方法的源代码吗?
  • @millimose:这是一个错误。现已编辑完毕。
  • @Joni :我没有得到 ypu 的评论?我的 JAVA 程序有一个本地方法声明,它的定义在一个 [.c] 文件中,在构建之后会创建一个 [.dll] 文件。没有本地方法正在调用 java 方法。
  • 您如何通过命令行或 IDE 运行您的应用程序?你究竟是如何设置属性java.library.path

标签: java c exception java-native-interface unsatisfiedlinkerror


【解决方案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++ 函数来重现它;以下不满足的链接异常正确地说明了定义的参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 2015-07-09
    • 1970-01-01
    • 2022-01-21
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多