Java JNI UnsatisfiedLinkError C指向指针的char指针

时间:2016-07-11 13:30:19

标签: java c++ types java-native-interface

您好我正在开发一个项目,其中C ++框架将集成到java程序中,因此我开始探索JNI。我目前正在努力进行类型转换以及应该在java本机方法中声明哪些参数类型,因为我是C ++的新手。

在cpp文件中,我有以下方法:

using namespace std;

int main(int argc,char**argv)
{
  //do stuff
} 

我对应的java类看起来像这样:

public class JniTest {

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

public JniTest() {

    char[][] arguments = new char[][] {"resourceFile1.txt".toCharArray(), "resourceFile2.txt".toCharArray()};
    main(2, arguments);
}

public native int main(int argc, char[][] argv);

}

java类的头文件如下:

#include <jni.h>
/* Header for class testPackage_JniTest */

#ifndef _Included_testPackage_JniTest
#define _Included_testPackage_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     testPackage_JniTest
 * Method:    main
 * Signature: (I[[C)I
 */
JNIEXPORT jint JNICALL Java_testPackage_JniTest_main
  (JNIEnv *, jobject, jint, jobjectArray);

#ifdef __cplusplus
}
#endif
#endif

当我尝试运行它时,我收到以下错误:

Exception in thread "main" java.lang.UnsatisfiedLinkError: 
testPackage.JniTest.main(I[Ljava/lang/String;)I
    at testPackage.JniTest.main(Native Method)
    at testPackage.JniTest.<init>(JniTest.java:14)
    at testPackage.Main.main(Main.java:6)

我已经使用谷歌,JNI API参考等来查找Java和C ++之间的类型匹配,但是找不到如何处理Java中指针类型的char指针。对于与cpp框架中的char **匹配的argv参数,Java类中的实际类型定义是什么?

1 个答案:

答案 0 :(得分:0)

当JVM尝试调用本机方法时 - 它希望您已将其实现为指向使用javah生成的标头的函数。即你的图书馆必须包含

JNIEXPORT jint JNICALL Java_testPackage_JniTest_main
  (JNIEnv *, jobject, jint, jobjectArray) {
    /* do stuff */
}

被捕获的异常是声明,本机方法没有实现。

接下来,将arguments传递给char数组而不是像String数组一样方便得多。

public JniTest() {

    String[] arguments = new String[] {"resourceFile1.txt", "resourceFile2.txt"};
    main(2, arguments);
}

public native int main(int argc, String[] argv);

}

在C ++中,你可以通过下一个方式获得args:

JNIEXPORT jint JNICALL Java_testPackage_JniTest_main (JNIEnv *, jobject thiz, jint argc, jobjectArray argv) {
    for(jsize i = 0; i < env->GetArrayLength(argv); i++) {
        jstring str = (jstring)env->GetObjectArrayElement(argv, i);
        const char *c_str = env->GetStringUTFChars(str, NULL);
        /* do whatever you want with c_str */
        env->ReleaseStringUTFChars(str, c_str);
    }

    /* ... */
}