JNA非const String结构的成员

时间:2015-08-19 14:42:16

标签: string struct const jna

我有一个C函数,它需要一个包含非const String的结构。

typedef struct _A {
  char* str;
} A;

void myFunc(A* aptr) { ... }

我已经尝试了很长时间通过JNA传递这个东西,但到目前为止还没有管理。

public class A extends Structure {
  public String str;
  protected List getFieldOrder() { ...
}

不起作用,因为String将变为const char *而不是我需要的char *。

public class A extends Structure {
  public byte[] str;
  protected List getFieldOrder() { ...
}

不起作用,因为结构中的字节数组变成了连续的内存,而不是指针。

我知道我可以使用Memory并复制字符串来完成。但我无法想象这是做这件事的首选方式。

我也试过像

这样的东西
public class NonConstStringMember extends Structure {
  public static class ByReference extends NonConstStringMember implements Structure.ByReference {}        
  public byte[] stringMember;
  protected List getFieldOrder() { ...
}

public class A extends Structure {
  public NonConstStringMember.ByReference str;
}

但它也不起作用,可能是因为对齐问题。

使用JNA执行此操作的首选方法是什么?

1 个答案:

答案 0 :(得分:2)

假设您希望它指向您可以写入的任意缓冲区,请使用Pointer(如果您正在分配缓冲区,则为其分配Memory值。

然后使用Pointer.getString(0)Pointer.setString(0, s)来操作缓冲区内容。

修改 Windows库通常具有大多数函数的ascii或unicode版本。虽然在大多数情况下您可以定义单个Structure以便在两种情况下使用,但有时您需要提供一些额外的处理以确保使用正确的类型。由于这两种模式很少(如果有的话)同时使用,因此JNA将选项设置为默认为一个或另一个(自动映射到右侧函数后缀,并自动将String映射到本机const char*const wchar_t*取决于模式。)

如果使用unicode模式,则使用setWideString(),否则使用setString(),或者在Structure上设置一些访问者以自动处理。例如:

class MyStructure extends Structure {
    private static final boolean ASCII = Boolean.getBoolean("w32.ascii");
    public Pointer stringBuffer = new Memory(X);
    void setStringBuffer(String s) {
        stringBuffer.setString(0, s, ASCII);
    }
    String getStringBuffer() {
        return stringBuffer.getString(0, ASCII);
    }
}

修改 请注意,在大多数情况下,您应使用String作为字段类型,并依赖TypeMapper在适当的幕后使用WString(例如User32和{{ 3}})。