我尝试用JNA映射此c ++函数时遇到问题。
https://www.inventcom.net/fanuc-focas-library/program/cnc_rdexecprog
FWLIBAPI short WINAPI cnc_rdexecprog(unsigned short FlibHndl, unsigned short *length, short *blknum, char *data);
我在Java中尝试了这些映射,但不起作用:
short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, String data);
short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, Pointer data);
short cnc_rdexecprog(short FlibHndl, ShortByReference length, ShortByReference blknum, Memory data);
第一个映射有效,但返回我发送的相同字符串,第二个和第三个显示此错误:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Invalid memory access
由于此线程,我得以使类似的功能正常工作:Use C++ DLL from Java with JNA
我认为问题出在输出参数“ char * data”中。如何映射此功能?
char *
类型需要一个字节的缓冲区(C中的字符)。
Java的String
类型是不可变的(const char *
),因此本机代码无法修改它,正如您所观察到的。 Pointer
类型可以使用,但是如您从错误消息中看到的那样,它并不指向分配的内存。 Memory
也可以工作(并扩展Pointer
),但需要您实际使用参数分配内存。例如:
Memory buffer = new Memory(bufferSize);
您可以将buffer
作为Pointer
或Memory
传递给您的方法,它将起作用。
这里的问题是确定bufferSize
的值。 the API会在这里帮助您:
length [in / out]指定显示的变量的地址要读取的字符数。将字符数设置为读取到此变量* length(length)。看完后,数实际读取的字符在此变量中设置* length(length)再次。
您需要协调缓冲区的大小和您在第二个参数中传递的长度。请查阅文档以查看是否有任何常量定义所需字符串的最大长度,然后使用该常量。 (根据我自己的评论,它可能是MAX_PROG_SIZE
(1024 * 2),并为空终止符添加了一个额外的字节。但是您应该自己对此进行验证。)
如果不存在,则标准的JNA习惯用法是:
EW_LENGTH
(2))或者,您可以从更大的值开始。
在所有情况下,请记住在实际最大字符串长度上加1以说明空终止符。