【问题标题】:Why Is JNA Not Mapping char** to String[]?为什么 JNA 没有将 char** 映射到 String[]?
【发布时间】:2023-03-31 07:21:01
【问题描述】:

我正在尝试使用 JNA 将 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确实似乎允许程序启动,但我不确定如何转换我的 @987654329 @ 到其中任何一种类型中。

【问题讨论】:

    标签: java jna


    【解决方案1】:

    主要原因是 JNI/JNA 使用原始类型。字符串实例是非原始对象(即使类在 java.lang 包中),因此具有与 C 代码不兼容的内存 Java 表示。作为信息,这个对象的表示存储了一种结构:对类(字符串)的引用对内部数组表示的引用,然后数组在内存中也有自己的表示。

    您的选择是将字符串从/转换为字节,您需要使用字符集:

    发送字符串

    "My string".getBytes(StandardCharsets.UTF_8)
    

    接收

    new String(bytes,StandardCharsets.UTF_8)
    

    【讨论】:

    【解决方案2】:

    事实证明,您可以创建一个com.sun.jna.StringArray,而不是使用String[]

    所以它变成native Foo(..., StringArray bar, ...) 并调用你只需包装String[] 的函数:

    String[] array = new String[n];
    
    DLL.Foo(..., new StringArray(array), ...);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-05
      • 2020-01-19
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多