Java 为什么JNA没有将字符**映射到字符串[]?

Java 为什么JNA没有将字符**映射到字符串[]?,java,jna,Java,Jna,我正在尝试使用JNA将java程序链接到dll 在我的C++ DLL中,我有一个函数,它包含了 char **/COD>。这意味着在Java中应该映射到String[] 据我所知,Foo(…,char**bar,…)应该变成native Foo(…,String[]bar,…)。然而,当我试图运行该程序时,我得到一个异常 java.lang.ExceptionInInitializerError Caused by: java.lang.IllegalArgumentException: cla

我正在尝试使用JNA将java程序链接到dll

在我的C++ DLL中,我有一个函数,它包含了<代码> char **/COD>。这意味着在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.lang.ExceptionInInitializeError
原因:java.lang.IllegalArgumentException:class[Ljava.lang.String;不是受支持的参数类型(在类DLL的方法Foo中)
位于com.sun.jna.Native.register(Native.java:1604)
位于com.sun.jna.Native.register(Native.java:1529)
位于com.sun.jna.Native.register(Native.java:1252)
在DLL上。(TrajParser.java:28)

如果我将java端的签名更改为
byte[]
PointerByReference
似乎允许程序启动,但我不确定如何将我的
String[]
转换为这两种类型中的任何一种。

主要原因是JNI/JNA使用基元类型。String实例不是基元对象(即使类在java.lang包中),也要有一个与C代码不兼容的内存中java表示对内部数组表示形式的引用,那么数组也有自己的内存表示形式

您可以选择将字符串从字节转换为字节,您需要使用字符集:

发送字符串

"My string".getBytes(StandardCharsets.UTF_8)
接收

new String(bytes,StandardCharsets.UTF_8)

事实证明,您可以创建一个
com.sun.jna.StringArray

因此它变成了
native Foo(…,StringArray bar,…)
,要调用该函数,只需包装一个
String[]

String[] array = new String[n];

DLL.Foo(..., new StringArray(array), ...);

这是否意味着无法将字符串数组传递到dll中,因为jna不允许使用二维数组?因为
string[]
必须归结为
byte[][]
,对吗?对于二维数组,您将需要像下面这样使用JNIEnv:对不起,我没有完整的工作示例