pythontypedef用法_如何在python中使用ctypes重载C库的弱声明函数?

您很困惑:弱符号在链接时处理,而您在运行时“操作”.链接器可能无法知道您的Python回调函数.尽管它不是官方消息,但请查看[Wikipedia]: Weak symbol以获取更多详细信息.另外,[Python 3]: ctypes – A foreign function library for Python.这是一个小演示.

libtest.c:

#include

int __attribute__((weak)) custom_callback(int a) {

printf("Callback not redefined,a);

return 0;

}

int multiply(int a,int b) {

custom_callback(a);

return a * b;

}

callback.c:

#include

int custom_callback(int a) {

printf("C callback redefinition,a);

return 0;

}

code.py:

#!/usr/bin/env python3

import sys

import ctypes

DLL_NAME = "./libtest.so"

CALLBACKFUNCTYPE = ctypes.CFUNCTYPE(ctypes.c_int,ctypes.c_int)

def py_callback_func(a):

print("PY callback redefinition",a)

return 0

def main(argv):

dll_name = argv[0] if argv else DLL_NAME

dll = ctypes.CDLL(dll_name)

multiply = dll.multiply

multiply.argtypes = [ctypes.c_int,ctypes.c_int]

multiply.restype = ctypes.c_int

#dll.custom_callback(3)

#dll.custom_callback = CALLBACKFUNCTYPE(py_callback_func)

#dll.custom_callback(3)

res = multiply(5,10)

if __name__ == "__main__":

print("Python {:s} on {:s}\n".format(sys.version,sys.platform))

main(sys.argv[1:])

print("Done.")

输出:

06003

如图所示,可见__attribute __((weak))效果.另外,关于注释的代码(尝试设置.dll函数):它仅在ctypes代理级别运行,而不会更改.dll代码(这很荒谬).

关于您的问题,有两种解决方法.这是一个使用指针的指针,该指针具有这样的回调函数.可以通过设置函数从外部设置指针(也可以导出).

libtest.c:

#include

#define EXEC_CALLBACK(X) \

if (pCallback) { \

pCallback(X); \

} else { \

fallbackCallback(X); \

}

typedef int (*CustomCallbackPtr)(int a);

static CustomCallbackPtr pCallback = NULL;

static int fallbackCallback(int a) {

printf("Callback not redefined,int b) {

EXEC_CALLBACK(a);

return a * b;

}

void setCallback(CustomCallbackPtr ptr) {

pCallback = ptr;

}

code.py:

#!/usr/bin/env python3

import sys

import ctypes

DLL_NAME = "./libtest.so"

CALLBACKFUNCTYPE = ctypes.CFUNCTYPE(ctypes.c_int,a)

return 0

def main():

dll = ctypes.CDLL(DLL_NAME)

multiply = dll.multiply

multiply.argtypes = [ctypes.c_int,ctypes.c_int]

multiply.restype = ctypes.c_int

set_callback = dll.setCallback

set_callback.argtypes = [CALLBACKFUNCTYPE]

multiply(5,10)

set_callback(CALLBACKFUNCTYPE(py_callback_func))

multiply(5,10)

set_callback(ctypes.cast(ctypes.c_void_p(),CALLBACKFUNCTYPE))

multiply(5,sys.platform))

main()

print("Done.")

输出:

06006

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值