JNI UnsatisfiedLinkError虽然一切似乎都很好

时间:2014-04-11 14:06:31

标签: java java-native-interface

我正在尝试使用java中的本机库。 vendor向我提供了相应的java文件(可以在“最新的JNI实现”下找到here

此外,我设置了-Djava.library.path="D:\*absolutePathToDLLFolder*",我尝试了一个相对路径,结果相同。

现在运行我的小应用程序时出现以下错误:

java.lang.UnsatisfiedLinkError: com.neurosky.thinkgear.ThinkGear.GetDriverVersion()I
    at com.neurosky.thinkgear.ThinkGear.GetDriverVersion(Native Method)
    at eu.expandable.mindwave.Start.main(Start.java:23)

这是我的主要班级:

package eu.expandable.mindwave;

import com.neurosky.thinkgear.ThinkGear;

/**
 *
 * @author Andre
 */
public class Start {

    public static void main(String[] args){
        System.out.println("Mindwave Test");

        //testing if os is 32bit
        //otherwise it wont work (under windows)
        int arc = Integer.valueOf(System.getProperty("sun.arch.data.model"));
        if(arc != 32) {
            System.err.println("Sorry, only 32bit platforms are supported");
            System.exit(0);
        }

        try {
            System.out.println("Mindwave Driver version: " + ThinkGear.GetDriverVersion());
        }catch(UnsatisfiedLinkError e){
            System.err.println("Are you sure the library is existing?");
            System.out.println("Will exit now");
            e.printStackTrace();
            System.exit(-1);
        }
        System.out.println("Trying to build a connection...");
        int connID = ThinkGear.GetNewConnectionId();
        System.out.println("Done. Connection ID is: " + connID);



        System.out.println("Release connection");
        ThinkGear.FreeConnection(connID);
        System.out.println("Connection is freed");
        System.out.println("Exit");

    }

}

我认为我的代码是正确的,但由于某种原因它仍然崩溃。 我在Windows 7 64位和Java 8(32位)下运行。

2 个答案:

答案 0 :(得分:0)

这是一个可以帮助您识别问题的PD程序。我看到你已经检查了32对64但是我在这个程序中留下了这个检查,因为它可能会在以后帮助其他人。

将以下内容添加到程序中,以确定两个运行时环境之间的arch和load路径的差异。调查路径/拱门的任何差异。

 System.out.println(System.getProperty("java.library.path"));
 System.out.println(System.getProperty("sun.arch.data.model"));

您可以使用dumpbin.exe实用程序来标识正在加载的DLL所需的依赖项。 确保存在依赖项。 用法示例:

C:> dumpbin /imports your.dll 

Dump of file your.dll
File Type: DLL
  Section contains the following imports:
    **KERNEL32.dll**

您可以使用where.exe命令查找依赖项的位置。 用法示例:

C:>where KERNEL32.dll
    C:\Windows\System32\kernel32.dll

如果你看到:

C:>where KERNEL32.dll
    INFO: Could not find files for the given pattern(s)

调查依赖DLL不在路径上的原因。

您可以使用dumpbin.exe命令检查64位与32位 例如:

C:>dumpbin /headers yourd.dll

 Dump of file yourd.dll
 PE signature found
 File Type: DLL
 FILE HEADER VALUES
         14C machine (x86)    <-- 32bit DLL

C:>dumpbin /headers yourd.dll

 Dump of file yourd.dll
 PE signature found
 File Type: DLL
 FILE HEADER VALUES
         8664 machine (x64)    <-- 64bit DLL

调查主要/从属的任何32位与64位不匹配。如果您的JVM是32位,则需要使用32位DLL。如果您的JVM是64位,则需要使用64位DLL。 (可以在64位操作系统上运行32位JVM,但JNI DLL必须是32位(DLL与JVM匹配而不是操作系统)。

答案 1 :(得分:0)

  

java.lang.UnsatisfiedLinkError:com.neurosky.thinkgear.ThinkGear.GetDriverVersion()I

这意味着找到了库,JVM现在正在尝试在其中找到原生的方法。这里的问题是,上面给出了其原始签名的方法实际上并未在库中找到。您必须发布库的.h和.c文件,至少是相关的方法标题,以获得进一步的帮助。但是你应该运行

javah com.neurosky.thinkgear.ThinkGear

并将新生成的.h文件与该项目中的当前文件及其.c文件进行比较。