为什么 JNA 不将 char** 映射到 String[]?
Why Is JNA Not Mapping char** to String[]?
我正在尝试使用 JNA link java 程序到 dll。
在我的 C++ DLL 中,我有一个接受 char**
的函数。 JNA API 意味着应该映射到 Java 中的 String[]
。
据我所知 Foo(..., char** bar, ...)
应该变成 native Foo(..., String[] bar, ...)
。但是,当我尝试 运行 程序时出现异常。
java.lang.ExceptionInInitializerError
Caused by: java.lang.IllegalArgumentException: class [Ljava.lang.String; is not a supported argument type (in method Foo in class DLL)
at com.sun.jna.Native.register(Native.java:1604)
at com.sun.jna.Native.register(Native.java:1529)
at com.sun.jna.Native.register(Native.java:1252)
at DLL.<clinit>(TrajParser.java:28)
如果我将 java 端的签名更改为 byte[]
或 PointerByReference
它 确实 似乎允许程序启动,但我不确定如何将我的 String[]
转换为这两种类型中的任何一种。
主要原因是JNI/JNA使用原始类型。字符串实例是非原始对象(即使 classe 在 java.lang 包中),因此在内存中有一个与 C 代码不兼容的 Java 表示。有关信息,此对象的表示存储了一种结构:对 class(字符串)的引用 对内部数组表示的引用,然后该数组在内存中也有它自己的表示。
您的选择是转换字符串 from/to 字节,您需要使用字符集:
发送字符串
"My string".getBytes(StandardCharsets.UTF_8)
接收
new String(bytes,StandardCharsets.UTF_8)
事实证明,您可以创建 com.sun.jna.StringArray
而不是使用 String[]
所以它变成了 native Foo(..., StringArray bar, ...)
并调用函数你只需包装一个 String[]
:
String[] array = new String[n];
DLL.Foo(..., new StringArray(array), ...);
我正在尝试使用 JNA link java 程序到 dll。
在我的 C++ DLL 中,我有一个接受 char**
的函数。 JNA API 意味着应该映射到 Java 中的 String[]
。
据我所知 Foo(..., char** bar, ...)
应该变成 native Foo(..., String[] bar, ...)
。但是,当我尝试 运行 程序时出现异常。
java.lang.ExceptionInInitializerError
Caused by: java.lang.IllegalArgumentException: class [Ljava.lang.String; is not a supported argument type (in method Foo in class DLL)
at com.sun.jna.Native.register(Native.java:1604)
at com.sun.jna.Native.register(Native.java:1529)
at com.sun.jna.Native.register(Native.java:1252)
at DLL.<clinit>(TrajParser.java:28)
如果我将 java 端的签名更改为 byte[]
或 PointerByReference
它 确实 似乎允许程序启动,但我不确定如何将我的 String[]
转换为这两种类型中的任何一种。
主要原因是JNI/JNA使用原始类型。字符串实例是非原始对象(即使 classe 在 java.lang 包中),因此在内存中有一个与 C 代码不兼容的 Java 表示。有关信息,此对象的表示存储了一种结构:对 class(字符串)的引用 对内部数组表示的引用,然后该数组在内存中也有它自己的表示。
您的选择是转换字符串 from/to 字节,您需要使用字符集:
发送字符串
"My string".getBytes(StandardCharsets.UTF_8)
接收
new String(bytes,StandardCharsets.UTF_8)
事实证明,您可以创建 com.sun.jna.StringArray
String[]
所以它变成了 native Foo(..., StringArray bar, ...)
并调用函数你只需包装一个 String[]
:
String[] array = new String[n];
DLL.Foo(..., new StringArray(array), ...);