使用JNA映射c ++函数

问题描述 投票:1回答:1

我尝试用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”中。如何映射此功能?

java c++ dll jna
1个回答
0
投票

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

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

Memory buffer = new Memory(bufferSize);

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

这里的问题是确定bufferSize的值。 the API会在这里帮助您:

length [in / out]指定显示的变量的地址要读取的字符数。将字符数设置为读取到此变量* length(length)。看完后,数实际读取的字符在此变量中设置* length(length)再次。

您需要协调缓冲区的大小和您在第二个参数中传递的长度。请查阅文档以查看是否有任何常量定义所需字符串的最大长度,然后使用该常量。 (根据我自己的评论,它可能是MAX_PROG_SIZE(1024 * 2),并为空终止符添加了一个额外的字节。但是您应该自己对此进行验证。)

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

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

或者,您可以从更大的值开始。

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

© www.soinside.com 2019 - 2024. All rights reserved.