调用C子例程时出现JNI错误

时间:2011-07-11 04:02:36

标签: java c java-native-interface

我想从Java调用C子例程。我正在使用JNI。我创建了.java,.c和.h文件,并编译了一个DLL。所有文件都在同一个文件夹中。但是当我运行程序时,它会显示unsatisfiedlinkError。我哪里错了......?

在我学习JNI时,我使用的源代码来自:http://www.ibm.com/developerworks/java/tutorials/j-jni/section2.html以及我已经尝试过的内容:

  • 使用Code :: Blocks(ide)和GCC作为编译器
  • 创建一个dll
  • 从命令行使用GCC创建dll(参考http://sig9.com/node/35
  • 我使用Win7 32位,我猜上面的所有方法都生成32位DLL
  • 我找到的用于创建DLL(共享库)的所有解决方案都是针对MS VC / VCPP的,我现在在我的机器上没有这个。

问题出在哪里?生成DLL文件没有任何异常,但是当我运行Java代码时,它会抛出异常。


PS:如果有任何理论上的例子可以解释JNI的工作原理以及它的实际作用,那么请分享链接...

抛出的消息或异常:

    c:\myjava1>java Sample1
    Exception in thread "main" java.lang.UnsatisfiedLinkError: Sample1.intMethod(I)I
      at Sample1.intMethod(Native Method)
      at Sample1.main(Sample1.java:11)

在创建dll文件很多次后的一天结束时,我很确定它可能没有问题,路径有问题...我已经改变了 loadlibrary 使用加载方法的方法,但仍然没有运气,.....


如MOD建议: 我一直在讨论关于这个问题的帖子:在调用C子程序时JNI错误,我在这里发布所有代码,因为注释有限的字符... Sample1.c

#include "jni.h"
#include"Sample_Sample1.h"
JNIEXPORT jint JNICALL Java_Sample_Sample1_test(JNIEnv *env, jobject obj){
return(1);
}
void main(){}

Sample1.java

package Sample;

public class Sample1
{
public native int test();
static{ 
System.loadLibrary("Sample1");
}
public static void main(String[] args)
{
 Sample1 sample = new Sample1();
 System.out.println(sample.test());
 }
}

Sample_Sample1.h(使用javah -jni命令生成)

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

#ifndef _Included_Sample_Sample1
#define _Included_Sample_Sample1
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Sample_Sample1
 * Method:    test
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_Sample_Sample1_test
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

任何人都可以指导我在哪里出现问题吗?在之前的帖子中我提到我使用的代码是教程中的代码,但只是简单地说明我改变代码的东西......使用** java Sample.Sample1时“我得到了:

c:\ myjava1> java Sample.Sample1 线程“main”中的异常java.lang.UnsatisfiedLinkError:Sample.Sample1.test()I         在Sample.Sample1.test(本机方法)         在Sample.Sample1.main(Sample1.java:12)

4 个答案:

答案 0 :(得分:2)

您需要have your library explicitly set on your path

可能是您在那里使用的标志不太正确的情况。试试这个:

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at \
    -I[Java_HOME]/include -I[Java_HOME]/include/win32 \
    -shared -o Sample1.dll Sample1.c

来自MinGW GCC site

答案 1 :(得分:0)

您是否通过从存根C ++应用程序调用DLL来检查您的DLL?请特别注意您正在呼叫的方法的确切名称(包括大小写)。

UnsatisfiedLinkError的Javadoc说“如果Java虚拟机找不到声明为native的方法的适当的本地语言定义,则抛出”。这可能意味着名称拼写错误或者您的DLL不是JVM期望找到它的位置。

答案 2 :(得分:0)

最后使用System.load()方法解决了问题,System.loadLibrary()仍然不适用于我...它继续给出相同的异常,而且我认为问题出在.dll谢谢致所有支持和回应的人......

答案 3 :(得分:0)

花费2个小时并分析代码后。问题在于.dll / .so编译。下面的命令对我有用:

  

g ++ -dynamiclib HelloJni.cpp -I / usr / include / -I /usr/lib/jvm/java-1.8.0-openjdk-amd64/include/ -I / usr / lib /jvm/java-1.8.0-openjdk-amd64/include/linux/ -共享 -o libHelloJni.so

  

g ++ -dynamiclib HelloJni.cpp -I / usr / include / -I $ JAVA_HOME / include / -I $ JAVA_HOME / include / linux / -shared -o libHelloJni.so

以上命令适用于Linux。如果是 Windows ,请更改

[Java_HOME] / include / linux / ---> [Java_HOME] / include / win /

Mac:

$Java_HOME/include/linux/  --->  $Java_HOME/include/darwin/