简体   繁体   English

使用带有JNA的TCHAR缓冲区

[英]Using TCHAR buffer with JNA

I am trying to build some Java code to call some networking functions in a DLL written in VC++. 我正在尝试构建一些Java代码来调用用VC ++编写的DLL中的一些网络函数。 The functions exported include (from the .h file) 导出的函数包括(来自.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);

the first 4 of which I have mapped as follows: 我绘制的前4个如下:

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

All of these seem to be working OK. 所有这些似乎都运作正常。 My problem comes when I try to map the arguments for CsilGetData - the code is presumably expecting a pointer to an array of Unicode characters whose size is defined in the second argument, but I have so far been unable to come up with the correct Java mapping. 我的问题出现在我尝试映射CsilGetData的参数时 - 代码可能是指向一个Unicode字符数组的指针,其大小在第二个参数中定义,但到目前为止我还无法提供正确的Java映射。 When called, the buffer will be loaded with data by the native code, and the data will then be read by the calling Java code when the function returns. 调用时,缓冲区将由本机代码加载数据,然后在函数返回时由调用Java代码读取数据。

Can anyone provide an example of the correct way to do this? 任何人都可以提供正确的方法来做到这一点吗?

As suggested, I have tried as a test mapping CsilGetData as 正如所建议的,我已经尝试将CsilGetData作为测试映射

boolean CsilGetData(WString buffer, int bufflen)

and then calling it as follows 然后按如下方式调用它

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

but executing the call to CsilGetData gives 但是执行对CsilGetData的调用给出了

Exception in thread "main" java.lang.Error: Invalid memory access at com.sun.jna.Native.invokeInt(Native Method) at com.sun.jna.Function.invoke(Function.java:371) at com.sun.jna.Function.invoke(Function.java:315) at com.sun.jna.Library$Handler.invoke(Library.java:212) at com.sun.proxy.$Proxy0.CsilGetData(Unknown Source) at qeitest.Main.main(Main.java:66) 线程“main”中的异常java.lang.Error:com.sun.jna.Function.invoke(Function.java:371)com.sun.jna.Native.invokeInt(本机方法)的内存访问无效位于com.sun.proxy的com.sun.jna.Library $ Handler.invoke(Library.java:212)的.jna.Function.invoke(Function.java:315).qeitest的$ Proxy0.CsilGetData(未知来源)。 Main.main(Main.java:66)

Technomage suggested using char[] instead, so I revised the code to define the mapping as Technomage建议使用char [],所以我修改了代码以将映射定义为

boolean CsilGetData(char[] buffer, int bufflen)

and then invoked it as 然后将其作为调用

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

but I still get the same Memory Access exception. 但我仍然得到相同的内存访问异常。 I believe this is the correct mapping, but I have also tried byte[] with the same result. 我相信这是正确的映射,但我也尝试了具有相同结果的byte []。

Your buffer needs to be writable. 你的缓冲区需要是可写的。 String and WString are read-only. StringWString是只读的。

Use char[] for native wchar_t[] and byte[] for native char[] ; char[]用于本机wchar_t[] ,将byte[]用于native char[] ; you can then use Native.toString() to extract the native NUL-terminated string. 然后,您可以使用Native.toString()来提取本机NUL终止的字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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