如何像 python ctypes 那样指定 JNR 指针
Posted
技术标签:
【中文标题】如何像 python ctypes 那样指定 JNR 指针【英文标题】:how to specify a JNR Pointer like that of python ctypes 【发布时间】: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
字段键入为指向字符串的指针?
【问题讨论】:
【参考方案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());
【讨论】:
以上是关于如何像 python ctypes 那样指定 JNR 指针的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 ctypes 停止和重新启动从 python 运行的 C++ 代码
像 nm -D 或 readelf -s 一样,使用 python ctypes 列出动态符号?