0

JNA と Jnaerator を使用して生成されたコードを使用して dll を呼び出しています。メソッドの 1 つは文字列を必要とし、JNA 署名は ByteBuffer を取ります。

ByteBuffer を直接 (ByteBuffer.allocateDirect) および間接 (ByteBuffer.wrap) として割り当てようとしましたが、どちらの場合、dll に到達する文字列にランダムな文字が追加される場合があります (例: ReceiptÚeœ )。元の byte[] はそこにあります (receipt = 52 65 63 65 69 70 74) が、可変数の追加のランダム バイト (01 da 65 9c 19) もあります。ランダムに文字列が正しく、追加のバイトがありません。

JNAの代わりにBridJを使用して同等のコードを試しました(メソッドのシグネチャはポインター名を取ります)。その場合、正常に動作します。残念ながら、私は com.sun.jna.platform.win32 クラスを使用する必要があるため、BridJ に切り替えることはできません。 -user32-missing-methods )

ネイティブ宣言:

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、ライブラリを type-map に構成しますString(「参考文献」を参照W32APIOptions.UNICODE_OPTIONS)。

于 2015-07-29T17:54:15.240 に答える
0

文字列を含むバイト配列を渡しているが、null で終了する文字列ではないことが起こっていると思います。余分な位置を持つバイト配列を作成する必要があります。そのラス位置を 0 に設定し、文字列をそのバイト配列にコピーします。

于 2015-10-01T08:48:50.723 に答える