gpt4 book ai didi

python - 通过 Ctypes 从 C 到 Python - 将函数指针的结构包装到静态函数

转载 作者:太空宇宙 更新时间:2023-11-04 02:27:41 25 4
gpt4 key购买 nike

我在 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 中很好,在 C 中调用 fn1 就像 DATAFUNC.fn1(..., ...),但是如何将这样的东西包裹起来以便 fn1 可以在带有 ctypes 的 python 中调用?

示例 python

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

结果 <_FuncPtr object at 0x6ffffcd7430>

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

最佳答案

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

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

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

  • 结构。通过子类化定义 Python 对应物ctypes.Structure

  • 函数指针(适用于您的案例)。使用 ctypes.CFUNCTYPE

    定义它们

我准备了一个简化的示例来说明上述内容。请注意,为了简单起见,我没有进行任何错误处理(检查 NULL(您应该))。

dll00.h:

struct Data {
int i;
};


typedef struct {
int (* const Func00Ptr) (struct Data*, const char*);
} DataFunc;


extern DataFunc const dataFunc;

dll00.c:

#include <stdio.h>

#include "dll00.h"


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


DataFunc const dataFunc = { &func00 };

code00.py:

#!/usr/bin/env python

import ctypes as ct
import sys


DLL_NAME = "./dll00.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")


class Data(ct.Structure):
_fields_ = (
("i", ct.c_int),
)


Func00Type = ct.CFUNCTYPE(ct.c_int, ct.POINTER(Data), ct.c_char_p)


class DataFunc(ct.Structure):
_fields_ = (
("func00", Func00Type),
)


def main(*argv):
data = Data(127)
dll = ct.CDLL(DLL_NAME)
data_func = DataFunc.in_dll(dll, "dataFunc")
ret = data_func.func00(ct.byref(data), "abcd".encode())
print("Function returned: {:d}".format(ret))


if __name__ == "__main__":
print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
64 if sys.maxsize > 0x100000000 else 32, sys.platform))
rc = main(*sys.argv[1:])
print("\nDone.")
sys.exit(rc)

输出:

[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q049962265]> ~/sopr.sh
### Set shorter prompt to better fit when pasted in StackOverflow (or other) pages ###

[064bit prompt]> ls
dll00.c dll00.h code00.py
[064bit prompt]> gcc -shared -fPIC -o dll00.so dll00.c
[064bit prompt]> ls
dll00.c dll00.h code.py dll00.so
[064bit prompt]> objdump -t dll00.so | grep dataFunc
0000000000200e10 g O .data.rel.ro 0000000000000008 dataFunc
[064bit prompt]> python code00.py
Python 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609] 064bit on linux

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

Done.

关于python - 通过 Ctypes 从 C 到 Python - 将函数指针的结构包装到静态函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49962265/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com