4

我正在使用 libusb—— http://sourceforge.net/apps/trac/libusb-win32/wiki

但是,我得到:

线程“主”java.lang.UnsatisfiedLinkError 中的异常:USBManager.usb_init()V

public class USBManager 
{   
    static{
        System.loadLibrary("libusb");   
    }

    native void usb_init();
    public USBManager()
    {       
        usb_init();     
    } 
}
4

5 回答 5

3

这个库有一个已经编写好的 Java 包装器。你为什么不试试呢?

于 2011-01-30T15:24:44.393 回答
2

你不能只使用 public native usb_init(); 然后像这样加载一个本机库,JNI 不是以这种方式实现的。

您使用 javah 创建一个 .h 文件,该文件可用于创建实现类中特定本机函数的库。

javac USBManager

创建一个与 javah 一起使用的类文件:

javah USBManager

这会在该位置生成一个名为“USBManager.h”的文件,该文件指定要在 .so/.dll 中实现的函数,以实现相关的本地函数。

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

#ifndef _Included_USBManager
#define _Included_USBManager
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     USBManager
 * Method:    usb_init
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_USBManager_usb_1init
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

因此,您需要导出一个名为“Java_USBManager_usb_1init”的函数,该函数采用指定的参数。

该功能无非是:

JNIEXPORT void JNICALL Java_USBManager_usb_1init (JNIEnv *, jobject) {
    usb_init();
}

Sun 开发人员的博客上有一个非常好的简单示例,但还有很多其他示例。

于 2011-01-30T09:30:48.797 回答
0

尝试 System.loadLibrary("usb");

于 2011-01-30T07:40:26.347 回答
0

要么找不到 usb.dll,请尝试使用绝对路径而不是 System.loadLibrary() 的 System.load() 来验证这一点。

另一个问题可能是 libusb 依赖于其他 DLL。使用Dependency Walker查看 libusb 引用了哪些 DLL。

另一个问题可能是,DLL 没有导出具有正确签名的函数。DLL 中应该有一个 USBManager_usb_init() 函数。用于javah创建正确的签名。

于 2011-01-30T09:03:42.100 回答
0

JNI 相当简约,jni 访问的任何函数都需要针对您的类编写的本机包装函数。工具 javah 生成一个包含所需包装器的标头。

要以简单的方式访问本机函数,请使用JNA

于 2011-01-30T18:58:25.183 回答