Java 为什么JNA没有将字符**映射到字符串[]?
我正在尝试使用JNA将java程序链接到dllJava 为什么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
在我的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:对不起,我没有完整的工作示例