0

我正在使用 JNA 调用 dll,并使用 Jnaerator 生成代码。其中一种方法需要一个字符串,而 JNA 签名采用一个 ByteBuffer。

我尝试将 ByteBuffer 分配为直接 (ByteBuffer.allocateDirect) 和间接 (ByteBuffer.wrap),但在这两种情况下,有时到达 dll 的字符串具有额外的随机字符(例如 ReceiptÚeœ )。原始字节 [] 在那里(收据 = 52 65 63 65 69 70 74),但还有可变数量的附加随机字节(01 da 65 9c 19)。随机字符串是正确的,没有额外的字节。

我尝试了使用 BridJ 而不是 JNA 的等效代码(方法签名采用指针名称),在这种情况下它可以正常工作。不幸的是,我无法切换到 BridJ,因为我需要使用 com.sun.jna.platform.win32 类,除非我可以为这些类生成 BridJ 替代品(https://stackoverflow.com/questions/31658862/jnaerator-bridj -user32-缺少方法

本机声明:

HRESULT extern WINAPI WFSOpen ( LPSTR lpszLogicalName, HAPP hApp, LPSTR lpszAppID,DWORD dwTraceLevel, DWORD dwTimeOut, DWORD dwSrvcVersionsRequired, LPWFSVERSION lpSrvcVersion, LPWFSVERSION lpSPIVersion, LPHSERVICE lphService);

JNAerator JNA代码:

//works
@Deprecated 
NativeLong WFSOpen(Pointer lpszLogicalName, Pointer hApp, Pointer lpszAppID, int dwTraceLevel, int dwTimeOut, int dwSrvcVersionsRequired, WFSVERSION lpSrvcVersion, WFSVERSION lpSPIVersion, ShortByReference lphService);
//does not work
NativeLong WFSOpen(ByteBuffer lpszLogicalName, Pointer hApp, ByteBuffer lpszAppID, int dwTraceLevel, int dwTimeOut, int dwSrvcVersionsRequired, WFSVERSION lpSrvcVersion, WFSVERSION lpSPIVersion, ShortBuffer lphService);

Java 调用工作(但已弃用)

Pointer m = new Memory(string.length() + 1); // WARNING: assumes ascii-only string
m.setString(0, string);
MsxfsLibrary.INSTANCE.WFSOpen(lpszLogicalName, lphApp.getValue(), lpszAppID, dwTraceLevel, dwTimeOut, dwSrvcVersionsRequired, lpSrvcVersion, lpSPIVersion, lphService);

Java调用不工作测试A:

lpszLogicalName = ByteBuffer.wrap(bytes);
 MsxfsLibrary.INSTANCE.WFSOpen(lpszLogicalName, lphApp.getValue(), lpszAppID, dwTraceLevel, dwTimeOut, dwSrvcVersionsRequired, lpSrvcVersion, lpSPIVersion, lphService);

Java调用不工作测试B:

byte[] bytes = string.getBytes();
return ByteBuffer.wrap(bytes);
ByteBuffer bb = ByteBuffer.allocateDirect(bytes.length);
bb.put(bytes);
lpszLogicalName = bb.position(0);
msxfsLibrary.WFSOpen(lpszLogicalName, lphApp.getValue(), lpszAppID, dwTraceLevel, dwTimeOut, dwSrvcVersionsRequired, lpSrvcVersion, lpSPIVersion, lphService);
4

2 回答 2

0

如果您指的是_wfsopen(),则它需要一个宽字符串。使用WString或将您的库配置为类型映射String(请参阅 参考资料W32APIOptions.UNICODE_OPTIONS)。

于 2015-07-29T17:54:15.240 回答
0

我认为正在发生的事情是您正在传递一个包含您的字符串但它不是以空字符结尾的字符串的字节数组。您应该创建一个具有额外位置的字节数组。将该 las 位置设置为 0 并将您的字符串复制到该字节数组中。

于 2015-10-01T08:48:50.723 回答