找不到JNA运行时相关库

时间:2015-04-17 10:13:13

标签: java jna

我正在尝试在JNA中使用预先存在的stdcall DLL,其中一个函数一直抱怨无法找到与运行时相关的dll。在同等的JNI版本中,我没有得到这个投诉,它按预期工作。

System.loadLibrary("MP300Com");

Map<String, Object> functionMapper = new HashMap<>();
functionMapper.put(
        Library.OPTION_FUNCTION_MAPPER, 
        new StdCallFunctionMapper());

library = (Mp300Library)Native.loadLibrary(
        "MP300Com", 
        Mp300Library.class, 
        functionMapper);

public interface Mp300Library extends StdCallLibrary {
    int USBEnumerateDevices(IntByReference pNbMP300, Pointer ppSerialList);
}

public static String[] USBEnumerateDevices() throws Mp300Exception {
    Memory pSerialList = new Memory(512);
    IntByReference pNbMP300 = new IntByReference();
    Pointer ppSerialList = new Memory(Pointer.SIZE);
    ppSerialList.setPointer(0, pSerialList);
    int status = library.USBEnumerateDevices(pNbMP300, ppSerialList);
    System.out.println(status); // 65525 = 0xfff5
    return null;
}

当我调用函数USBEnumerateDevices时,我得到返回值0xFFF5,根据手册的意思是“未找到MPDeviceDriver.dll”

文件MPDeviceDriver.dll与MP300Com.dll位于同一路径,两者都在c:\ windows \ sysWOW64中

我还尝试在其他加载之前和之后添加System.loadLibrary("MPDeviceDriver");,但没有成功。我可以验证它是否被JNA加载 - 因为我无法删除项目文件夹中的MPDeviceDriver.dll(它被锁定)。

如前所述,当JNI版本调用此函数时,我得到返回值0x0(ok)并且设备被正确枚举。摘录自JNI代码:

int nbMp = 0;
char devlist[512];
char *pList = devlist;
WORD ret = USBEnumerateDevices(&nbMp, &pList);  

使用依赖walker,我没有看到任何明显缺少的依赖项,而且,MPDeviceDriver.dll未列为依赖项。我猜它是由代码本身手动加载的。

我很肯定在JNA中调用USBEnumerateDevices的方式是正确的,因为当我用非常旧版本(不依赖于MPDeviceDriver.dll)替换MP300Com.dll时,设备会被正确枚举。 (pSerialList包含我的设备字符串)

Link to the function definition in the manual

1 个答案:

答案 0 :(得分:1)

在一位同事尝试了一些简化的测试后,它突然发挥了作用,在我尝试将调用的确切顺序转换为框架后,它再次无效。事实证明,这个特定的DLL是线程敏感的,并且以最扭曲的方式:

  • 如果加载DLL的线程和第一次使用的DLL的线程相同,则DLL在所有线程中工作。
  • 如果第一次使用DLL加载DLL和线程的线程不同,则这些线程都不能使用该DLL,但是从另一个ThreadGroup生成的另一个线程可以使用该DLL。