使用带有JNA的TCHAR缓冲区

时间:2013-12-18 17:28:58

标签: java c++ jna

我正在尝试构建一些Java代码来调用用VC ++编写的DLL中的一些网络函数。导出的函数包括(来自.h文件)

EX CS BL BOOL CD CsilInit(void);
EX CS BL BOOL CD CsilUnInit(void);
EX CS BL BOOL CD CsilConnect(TCHAR * server, TCHAR * service);
EX CS BL BOOL CD CsilRead(void);
EX CS BL BOOL CD CsilGetData(TCHAR buffer[], int bufflen);

我已经映射的前4个如下:

boolean CsilInit();
boolean CsilUnInit();
boolean CsilConnect(WString server, WString service);
boolean CsilRead();

所有这些似乎都运转正常。我的问题出现在我尝试映射CsilGetData的参数时 - 代码可能是指向一个Unicode字符数组的指针,其大小在第二个参数中定义,但到目前为止我还无法提供正确的Java映射。调用时,缓冲区将由本机代码加载数据,然后当函数返回时,调用Java代码将读取数据。

任何人都可以提供正确方法的示例吗?

正如所建议的那样,我尝试将CsilGetData作为测试映射为

boolean CsilGetData(WString buffer, int bufflen)

然后按如下方式调用

WString buffer = new WString("               ");
...
while (CSIL.INSTANCE.CsilGetData(buffer, buffer.length())) {
  System.out.print(buffer.toString());
}

但是执行对CsilGetData的调用会给出

  

线程“main”中的异常java.lang.Error:无效的内存访问           at com.sun.jna.Native.invokeInt(Native Method)           在com.sun.jna.Function.invoke(Function.java:371)           在com.sun.jna.Function.invoke(Function.java:315)           在com.sun.jna.Library $ Handler.invoke(Library.java:212)           at com.sun.proxy。$ Proxy0.CsilGetData(Unknown Source)           在qeitest.Main.main(Main.java:66)

Technomage建议使用char [],所以我修改了代码以将映射定义为

boolean CsilGetData(char[] buffer, int bufflen)

然后将其作为

调用
public static final int cnstBufLen = 2048;
char[] buffer = new char[cnstBufLen];
...
while (CSIL.INSTANCE.CsilGetData(buffer, cnstBufLen)) {
  System.out.print(buffer.toString());
}

但我仍然得到相同的内存访问异常。我相信这是正确的映射,但我也尝试了具有相同结果的byte []。

1 个答案:

答案 0 :(得分:0)

你的缓冲区需要是可写的。 StringWString是只读的。

对原生char[]使用wchar_t[],对原生byte[]使用char[];然后,您可以使用Native.toString()提取本地NUL终止的字符串。