通过Ctypes包装指向静态函数的函数指针结构

2024-10-01 17:21:29 发布

您现在位置:Python中文网/ 问答频道 /正文

我在C库中有这样的结构。 DataFn中的函数指针指向静态函数。在

.h.小时

struct Data {
    int i;
    int *array;
};

typedef struct {
    bool (* const fn1) (struct Data*, const char *source);
    ....
} DataFn;
extern DataFn const DATAFUNC

使用objdump,该表只包含DATAFUNC和gcc中的一些其他内容。在

在C语言中,调用fn1很好数据功能fn1(…,…),但是如何将类似的东西包装起来以便在python w/ctypes中调用fn1呢?在

python示例

^{pr2}$

结果 <_FuncPtr object at 0x6ffffcd7430>

This is similar, but there isn't a factory function.


Tags: 函数data静态结构arraystructint指向
1条回答
网友
1楼 · 发布于 2024-10-01 17:21:29

[Python 3.Docs]: ctypes - A foreign function library for Python包含解决此问题所需的所有内容。在

我认为缺少的主要部分是ctypes类型的in_dll方法(访问从dll导出的值部分)。在

除此之外,为了处理C数据,需要让Python知道数据格式。适用于:

  • 通过子类化ctypes.Structure来定义Python对应项
  • 函数指针(适用于您的案例)。使用ctypes.CFUNCTYPE定义它们

我准备了一个简单的例子来说明上述情况。请注意,我没有做任何错误处理(检查NULLs(这您应该),以保持简单。在

c.h

struct Data {
    int i;
};


typedef struct {
    int (* const fn1) (struct Data*, const char*);
} DataFn;


extern DataFn const DATAFUNC;

c.c

^{pr2}$

代码00.py

#!/usr/bin/env python3


import sys
from ctypes import c_int, c_char_p, Structure, CDLL, CFUNCTYPE, POINTER, byref


class Data(Structure):
    _fields_ = [
        ("i", c_int),
    ]


fn1_type = CFUNCTYPE(c_int, POINTER(Data), c_char_p)


class DataFn(Structure):
    _fields_ = [
        ("fn1", fn1_type),
    ]


def main():
    data = Data(127)
    dll = CDLL("./c.so")
    data_func = DataFn.in_dll(dll, "DATAFUNC")
    ret = data_func.fn1(byref(data), "abcd".encode())
    print("DATAFUNC.fn1 returned {:d}".format(ret))


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

输出

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049962265]> ls
c.c  c.h  code00.py
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049962265]> gcc -shared -fPIC -o c.so c.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049962265]> ls
c.c  c.h  code.py  c.so
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049962265]> objdump -t c.so | grep DATAFUNC
0000000000200e10 g     O .data.rel.ro   0000000000000008              DATAFUNC
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049962265]> python3 code00.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux

From C - Data.i: [127], source: [abcd]
DATAFUNC.fn1 returned -255

相关问题 更多 >

    热门问题