【问题标题】:how to specify a JNR Pointer like that of python ctypes如何像 python ctypes 那样指定 JNR 指针
【发布时间】:2018-12-04 08:02:22
【问题描述】:

使用 python 的 ctypes,可以指定一个带有类型的指针:

class METADATA(Structure):
    _fields_ = [("classes", c_int),
                ("names", POINTER(c_char_p))]

使用 JNR,它看起来像这样:

public static class Metadata extends Struct{

  public Metadata(jnr.ffi.Runtime rt) {
    super(rt);
  }

  public final Struct.Unsigned32 classes = new Struct.Unsigned32();
  public final Struct.Pointer names = new Struct.Pointer();
}

但是,是否可以将names 字段键入为指向字符串的指针?

【问题讨论】:

    标签: java jnr


    【解决方案1】:

    我不熟悉 python 的 ctypes 但假设 names 的类型是 char*char** 您可以尝试使用以下方法之一。

    对于共享库,

    #include <stdlib.h>
    #include <stdio.h>
    
    struct MyStruct {
        int classes;
        char *names;
        char **names2;
    };
    
    struct MyStruct *get_my_struct() {
        struct MyStruct *my_struct = malloc(sizeof(struct MyStruct));
        my_struct->classes = 42;
        my_struct->names = "My Names";
        char **names2 = calloc(2, sizeof(char *));
        names2[0] = "Stack";
        names2[1] = "Overflow";
        my_struct->names2 = names2;
        return my_struct;
    }
    

    结构体可以定义如下

    public static class MyStruct extends Struct {
      public MyStruct(Runtime runtime) {
        super(runtime);
      }
    
      public final Struct.Signed32 classes = new Struct.Signed32();
      // For char* the support is built-in
      public final Struct.String names = new Struct.UTF8StringRef();
      // For char** you could wrap a pointer and override getStringMemory
      public final UTF8StringRef[] names2 = UTF8StringRefArray(new Struct.Pointer(), 2);
    
      protected UTF8StringRef[] UTF8StringRefArray(Pointer pointer, int stringLength) {
        UTF8StringRef[] array = new UTF8StringRef[stringLength];
        for (int i = 0; i < array.length; i++) {
          int index = i;
          array[i] = new UTF8StringRef() {
            @Override
            protected jnr.ffi.Pointer getStringMemory() {
              return pointer.get().getPointer(getRuntime().addressSize() * index);
            }
          };
        }
        return array;
      }
    }
    

    对于上述情况,以下代码将打印42 My Names are Stack, Overflow

    public interface MyLib {
      MyStruct get_my_struct();
    }
    
    public static void main(String[] args) {
      MyLib mylib = LibraryLoader.create(MyLib.class).load("mylib.so");
      MyStruct myStruct = mylib.get_my_struct();
      System.out.printf("%d %s are %s, %s", myStruct.classes.get(), myStruct.names.get(),
          myStruct.names2[0].get(), myStruct.names2[1].get());
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-23
      • 2017-11-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-06
      • 1970-01-01
      • 1970-01-01
      • 2011-05-11
      相关资源
      最近更新 更多