Java中的链接错误

时间:2016-10-10 09:13:50

标签: java c java-native-interface

我收到以下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: model.JNIResultSet.getSpieler()[Lmodel/Spieler;
    at model.JNIResultSet.getSpieler(Native Method)
    at model.JNIResultSet.main(JNIResultSet.java:18)

我的java类看起来像这样:

package model;

public class Spieler {
private String vorname;
private String nachname;
private int trikotnummer;


public Spieler(String vorname, String nachname, int trikotnummer) {
    this.vorname = vorname;
    this.nachname = nachname;
    this.trikotnummer = trikotnummer;
}
}

package model;

public class JNIResultSet {

public JNIResultSet() { }

public native Spieler[] getSpieler();

static {
    System.loadLibrary("spieler");
}

public static void main(String[] args) {
    JNIResultSet jni = new JNIResultSet();
    Spieler s[] = jni.getSpieler();
    System.out.println("Laenge: " + s.length);
}


}

我的标题文件如下:

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

#ifndef _Included_model_JNIResultSet
#define _Included_model_JNIResultSet
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     model_JNIResultSet
* Method:    getSpieler
* Signature: ()[Lmodel/Spieler;
*/
JNIEXPORT jobjectArray JNICALL Java_model_JNIResultSet_getSpieler
(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

最后我的C代码看起来像这样:

JNIEXPORT jobjectArray JNICALL
JAVA_model_JNIResultSet_getSpieler(JNIEnv *env, jobject obj) {

Spieler *ptr = head;
jobjectArray ret;
int i;
jclass clazz = (*env)->FindClass(env, "model/Spieler");
jmethodID mid = (*env)->GetMethodID(env, clazz, "<init>", "(III)V");
jobject object; 

ret= (*env)->NewObjectArray(env, count,
        clazz,
        NULL);

for(i = 0; i < count; i++) {
    object = (*env)->NewObject(env, clazz, mid, ptr);
    (*env)->SetObjectArrayElement(env,
            ret, i, object);
    ptr = ptr->next;
}

return ret;
}

您对如何解决这个问题有什么建议吗? 我也不知道C代码是否正确,也许这就是问题所在?

我这样执行:

cd src
javac model/JNIResultSet.java
cd ..

cd bin
javah -jni model.JNIResultSet

gcc -fPIC -o libspieler.so -shared -I/usr/java/jdk1.8.0_73/include/ SharedTable.c -lc

java -Djava.library.path=/home/pupil/workspace/JNITableV2/bin/ model.JNIResultSet

可能这是我更新C代码的错误,但我认为这是错误的:

jclass clazz = (*env)->FindClass(env, "model/JNIResultSet");
jmethodID mid = (*env)->GetMethodID(env, clazz, "getSpieler", "()Lmodel/Spieler;");

nm -D报告:

U atoi
0000000000202088 B bss_start
00000000002020b0 B当前
w __cxa_finalize
0000000000202088 D _edata
00000000002022b8 B _end
你好了 0000000000000ef0 T _fini
 你打开了 w __gmon_start

00000000002020a8 B头
0000000000000948 T _init
0000000000000b35 T insertFirst
 你_IO_getc
 w _ITM_deregisterTMCloneTable
 w _ITM_registerTMCloneTable
0000000000000ca2 T JAVA_model_JNIResultSet_getSpieler
 w _Jv_RegisterClasses
 U malloc
 U memcpy
 U memset
0000000000000c49 T反向
 U strcpy
00000000002020c0 B string
 U strlen

2 个答案:

答案 0 :(得分:2)

getSpieler()方法可以声明为static;您可以在不实例化 JNIResultSet 类的情况下使用它。

mid 应该指向构造函数,而不是getSpieler(),但<init>签名是错误的:它应该是Ljava/lang/String;Ljava/lang/String;I而不是int } S:

jmethodID mid = (*env)->GetMethodID(env, clazz, "<init>", "(Ljava/lang/String;Ljava/lang/String;I)V");
…
jobject strVorname = (*env)->NewStringUTF(env, ptr->vorname);
jobject strNachname = (*env)->NewStringUTF(env, ptr->nachname);
object = (*env)->NewObject(env, clazz, mid, strVorname, strNachname, ptr->trikotnummer);

在继续下一步之前,请务必检查方法ID和对象是否为NULL。

关于未满足的链接,检查 libspieler.so 文件是否正常:运行nm -D以查看是否实际导出了JAVA_model_JNIResultSet_getSpieler完全按照生成的JAVA_model_JNIResultSet_getSpieler文件中的说明将Java_model_JNIResultSet_getSpieler重命名为.h

答案 1 :(得分:-2)

这可能是PATHLD_LIBRARY_PATH变量的问题(在Linux上,不确定Windows上的环境键是什么)。尝试将目录添加到这些变量,导出它们并运行应用程序。

在新会话中尝试。