通过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