简体   繁体   中英

JNA runtime dependent library not found

I'm trying to use a pre-existing stdcall DLL in JNA and one of the functions keeps complaining that a runtime-dependent dll can not be found. In an equivalent JNI version, I don't get this complaint and it works as expected.

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

When I call function USBEnumerateDevices I get the return value 0xFFF5, which according to the manual means "MPDeviceDriver.dll not found"

The file MPDeviceDriver.dll is in the same path as MP300Com.dll, and both are as well in c:\\windows\\sysWOW64

I also tried adding System.loadLibrary("MPDeviceDriver"); before and after the other load, without success. I can verify that it gets loaded — by JNA — because I can't delete the MPDeviceDriver.dll in my project folder (it's locked).

As said before, when the JNI version calls this function, I get return value 0x0 (ok) and the devices are enumerated correctly. Excerpt from the JNI code:

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

With dependency walker, I don't see any obviously missing dependencies, and moreover, MPDeviceDriver.dll is not listed as a dependency. I guess it gets loaded manually, by the code itself.

I'm positive the way of calling USBEnumerateDevices in JNA is correct, because when I replace MP300Com.dll with a very old version (one that doesn't depend on MPDeviceDriver.dll) the device gets enumerated correctly. (the pSerialList contains my the device string)

Link to the function definition in the manual

After a colleague tried some simplified tests it suddenly worked, and after I tried to translate the exact order of calls into the framework, it again didn't work. It turns out this specific DLL is thread-sensitive, and in a most twisted way:

  • If the thread loading the DLL and the thread using the DLL for the first time are the same, the DLL works in all threads.
  • If the thread loading the DLL and the thread using the DLL for the first time are different , none of those threads can use the DLL, but another thread spawned from another ThreadGroup could use the DLL.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM