gpt4 book ai didi

python - 让 C 库使用 ctypes 调用 python 函数

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

我有一个 C 语言的 DLL,适用于 Windows 平台,其结构类似于以下内容:

C 结构

typedef struct some_struct {
int (_stdcall *function)(int arg1, int arg2);
...
}SOME_STRUCT;

我已经定义了一个 python ctypes 结构来模仿它

Python 结构

class SOME_STRUCT(Structure):
_fields_ = [('function', POINTER(CFUNCTYPE(c_int, c_int, c_int))), ...]

C 代码中此结构的要点是注册一个回调函数,该回调函数在其自己的线程中的某些触发器上执行。如果可能的话,我希望能够做的是将该回调设置为 Python 函数,这样当从 C 代码调用 C 结构中的函数时,执行的是 python 函数。

我在 python 中尝试完成此操作(不起作用)的内容如下:

def func(arg1,arg2):
print('I was called!')
return 0

struct = SOME_STRUCT()
prototype = CFUNCTYPE(c_int, c_int, c_int)
struct.function = byref(prototype(func))

我得到的特定错误(这可能不是我唯一的问题)是它提示 struct.function 期待一个 LP_CFunctionType 实例但得到一个 CArgObject 实例。我怎样才能做我想做的事?

最佳答案

这是一个工作示例和测试 DLL 源。奇怪的是,当回调是结构的唯一成员时,我无法让它工作(崩溃)。这看起来像是一个错误,因为没有结构包装器或向结构添加第二个成员的回调使其工作。

注意事项:

  • WINFUNCTYPE__stdcall 一起使用。 CFUNCTYPE 用于 __cdecl
  • 你不需要 POINTERbyref 来让它工作。
  • @CALLBACK 装饰器等同于 func = CALLBACK(func)

测试.c

#include <stdio.h>

typedef int (__stdcall *CALLBACK)(int arg1, int arg2);

typedef struct some_struct {
CALLBACK function;
int other;
} SOME_STRUCT;

__declspec(dllexport) int func(SOME_STRUCT* pss)
{
printf("%d\n",pss->other);
return pss->function(1,2);
}

测试.py

from ctypes import *

CALLBACK = WINFUNCTYPE(c_int,c_int,c_int)

class SOME_STRUCT(Structure):
_fields_ = [('function', CALLBACK),
('other', c_int)]

@CALLBACK
def callback(arg1,arg2):
return arg1 + arg2

dll = CDLL('test')
dll.argtypes = POINTER(SOME_STRUCT),
dll.restype = c_int

struct = SOME_STRUCT(callback,7)
print(dll.func(byref(struct)))

输出

7
3

关于python - 让 C 库使用 ctypes 调用 python 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46495916/

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