编程语言
首页 > 编程语言> > 通过Ctypes将C转换为Python – 将函数指针的结构包含到静态函数中

通过Ctypes将C转换为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就像DATAFUNC.fn1(…,…),但是这样的东西怎么会被包裹起来所以fn1可以用python w / ctypes调用?

示例python

libc = ctypes.cdll.LoadLibrary("./data.so")
print(libc.DATAFUNC)

结果是
< _FuncPtr对象位于0x6ffffcd7430>

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

解决方法:

[Python 3.5]: ctypes – A foreign function library for Python包含解决此问题所需的一切.

我相信缺少的主要部分是ctypes类型的in_dll方法(访问从dll部分导出的值).

除此之外,为了使用C数据,您需要让Python知道数据格式.这适用于:

>结构.通过继承ctypes.Structure来定义Python对应物
>函数指针(适用于您的情况).使用ctypes.CFUNCTYPE定义它们

我准备了一个简化的例子,说明了上述内容.请注意,我没有做任何错误处理(检查NULL(你应该)),以保持简单.

c.h:

struct Data {
    int i;
};


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


extern DataFn const DATAFUNC;

C.C:

#include <stdio.h>
#include "c.h"


static int func1(struct Data *pData, const char *source) {
    printf("From C - Data.i: [%d], source: [%s]\n", pData->i, source);
    return -255;
}


DataFn const DATAFUNC = {&func1};

code.py:

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()

输出:

06003

标签:c-3,python,struct,ctypes,function-pointers
来源: https://codeday.me/bug/20191002/1841906.html