用JNA映射c++函数

Mapping c++ function with JNA

本文关键字:函数 c++ 映射 JNA      更新时间:2024-04-29

我在尝试用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

多亏了这个线程,我才能够让类似的功能发挥作用:将Java中的C++DLL与JNA 一起使用

我认为问题出在输出参数"char*data"上。如何映射此函数?

char *类型需要一个字节缓冲区(C中的字符(。

Java的String类型是不可变的(const char *(,因此本机代码无法修改它,正如您所观察到的那样。Pointer类型可以工作,但正如您从错误消息中看到的,它没有指向已分配的内存。Memory也起作用(并扩展了Pointer(,但需要使用参数实际分配内存。例如:

Memory buffer = new Memory(bufferSize);

您可以将buffer作为PointerMemory传递给您的方法,它就会起作用。

这里的问题是确定bufferSize的值应该是多少。这是API有益地告诉你的地方:

length[in/out]指定显示要读取的字符数。将字符数设置为读取到此变量*length(length(。阅读后实际读取的字符设置在此变量*长度(length(中再一次

您需要协调缓冲区的大小和在第二个参数中传递的长度。查阅文档,看看是否有任何常量定义了您期望的字符串的最大长度,并使用它。(基于此示例,它可能是MAX_PROG_SIZE(1024*2(,为空终止符添加了一个额外的字节。但你应该自己核实。(

如果这不存在,标准的JNA习惯用法是:

  • 声明一个大小并将其传递给本机函数(长度和分配的缓冲区应该匹配(
  • 检查是否有结果代码指示您没有提供足够的字符(可能是EW_LENGTH(2((
  • 使用较大的缓冲区重复此操作,直到字符串适合为止

或者,您可以从一个大得多的值开始。

在所有情况下,请记住在实际的最大字符串长度上加1,以说明null终止符。