2015-04-17 132 views
1

我想在JNA中使用预先存在的stdcall DLL,并且其中一个函数一直在抱怨找不到与运行时相关的DLL。在一个等价的JNI版本中,我没有得到这个投诉,它按预期工作。未找到JNA运行时依赖库

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); 

随着Dependency Walker中,我没有看到任何明显缺少的依赖关系,而且,MPDeviceDriver.dll没有被列为依赖关系。我猜它是由代码本身手动加载的。

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

Link to the function definition in the manual

回答

1

后同事尝试了一些简单的测试中,它突然的工作,之后我试图调用的确切顺序翻译成框架,它再次没有工作。事实证明,这种特定的DLL是线程敏感,并且在最扭曲的方式:

  • 如果线程加载使用DLL DLL和线程首次是相同的,该DLL工程全部个主题。
  • 如果线程首次使用DLL加载DLL和线程是不同,那些线程都不能使用该DLL,但是从另一个ThreadGroup派生的另一个线程可以使用该DLL。