【问题标题】:c - Java: UnsatisfiedLinkError on natie method callc - Java:natie 方法调用上的 UnsatisfiedLinkError
【发布时间】:2013-12-02 23:21:22
【问题描述】:

我正在学习 JNI。 我创建了一个简单的 java 类:

package asd.jni;

public class PrintJNI {

  public native String print();

  static{
   try{
      System.out.println("loading libPrint");
      System.load("C:/DeLauri/WorkSpaceC_CPP/Print2/Debug/libPrint.dll");  
      System.out.println("libPrint loaded");
  }catch(UnsatisfiedLinkError e){
      System.out.println("error "+e.toString());
      e.printStackTrace();
  }
 }
}

手动调用 javah -jni 我创建 asd_jni_PrintJNI.h:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class asd_jni_PrintJNI */

#ifndef _Included_asd_jni_PrintJNI
#define _Included_asd_jni_PrintJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     asd_jni_PrintJNI
 * Method:    print
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_asd_jni_PrintJNI_print
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

在 Eclipse CDT 中,我创建了一个名为“Print”的 C 项目,并在其中创建了一个 Print.c:

#include <jni.h>
#include <stdio.h>
#include "asd_jni_PrintJNI.h"

JNIEXPORT jstring JNICALL Java_asd_jni_PrintJNI_print  (JNIEnv *env, jobject obj) {

printf("aasdasdadasd");
const char rtn[10]  = "Hello \n";

printf("aasdasdadasd");
return (*env)->NewStringUTF(env, rtn);
}

一切都编译成功,但是当我运行我的主类时: 包装 asd;

import asd.jni.PrintJNI;

public class StartPrintJNI {

/**
 * @param args
 */
public static void main(String[] args) {

    try{
        PrintJNI print = new PrintJNI();

        System.out.println("call");
        String cStrg = print.print();
        System.out.println("called");
        System.out.println(cStrg);
    }catch(UnsatisfiedLinkError e){
          System.out.println("error in main "+e.toString());
          e.printStackTrace();
      }catch(Exception e){
         System.out.println("2 "+ e.getMessage());
         e.printStackTrace();
     }

}

}

我有以下错误:

loading libPrint
libPrint loaded
call
error in main java.lang.UnsatisfiedLinkError: asd/jni/PrintJNI.print()Ljava/lang/String;
java.lang.UnsatisfiedLinkError: asd/jni/PrintJNI.print()Ljava/lang/String;
at asd.StartPrintJNI.main(StartPrintJNI.java:16)

有人可以帮助我吗? 谢谢

更新:我正在使用 Eclipse/Eclipse CDT IDE 中的 MinGW 在 Windows 7 上进行这些测试

【问题讨论】:

  • 你检查你的 DLL 导出的函数名了吗?您可以使用dependencywalker.com 来查看它。很可能你的名字被弄错了。
  • 这是一个好问题!DLL 文件的名称是 libPrint.dll 但我不确定 dll 中的函数名称是否正确。我不能在我工作的电脑上安装这个软件,但我会在谷歌上找到如何查看里面的 dll 文件。
  • 如果我通过eclipse CDT浏览dll生成的文件,我找到了一个名为_Java_asd_jni_PrintJNI_print@8()的方法

标签: java c eclipse java-native-interface eclipse-cdt


【解决方案1】:

将 DLL 与 MingW 链接时,使用

-Wl,--export-all-symbols -Wl,--add-stdcall-alias -m32 -shared

导出函数的非修饰副本。

不要改变你的方法签名;你在掩盖你的问题。

【讨论】:

    【解决方案2】:

    我解决了我的问题。我刚刚在“asd_jni_PrintJNI.h”中的方法定义中添加了一个下划线“_”:

    JNIEXPORT jstring JNICALL _Java_asd_jni_PrintJNI_print
    (JNIEnv *, jobject)
    

    因此在“Print.c”中更改方法的名称:

    JNIEXPORT jstring JNICALL _Java_asd_jni_PrintJNI_print  (JNIEnv *env, jobject obj)
    

    【讨论】:

    • 这是不正确的。使用 MingW,您需要为您的 DLL 导出未损坏的别名
    猜你喜欢
    • 1970-01-01
    • 2014-05-01
    • 1970-01-01
    • 2018-02-24
    • 2012-01-12
    • 1970-01-01
    • 2020-01-25
    • 1970-01-01
    • 2012-06-02
    相关资源
    最近更新 更多