【问题标题】:Mapping c++ function with JNA用 JNA 映射 c++ 函数
【发布时间】:2020-04-30 10:46:41
【问题描述】:

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

    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) 再次。

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

    如果不存在,标准 JNA 习语是:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-11
      • 1970-01-01
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多