高级语言调用C接口(二)回调函数(4)Python

前面2篇分别说了java和c#调用C接口,参数为回调函数,回调函数中参数是结构体指针。

接下来说下python的调用方法。

from ctypes import *
import sys

class stPayResult(Structure):
    _pack_ = 4  # 根据实际C结构体的对齐方式设置(常见值为1,4,8)
    _fields_ = [
        ("place", enPlace),
        ("errCode", c_char_p),
        ("errInfo", c_char_p),
        ("seqId", c_char_p),
        ("merOrderId", c_char_p),
        ("srcReserve", c_char_p),
        ("attachedData", c_char_p),
        ("totalAmount", c_char_p),
        ("couponAmount", c_char_p),
        ("payAmount", c_char_p),
        ("payTime", c_char_p),
        ("orderCreateTime", c_char_p),
        ("status", c_char_p)
    ]

# 定义回调类型(严格匹配C函数调用约定)
OnPayResult = CFUNCTYPE(None, POINTER(stPayResult))

# 加载C库(示例使用Windows DLL)
try:
    sdk = CDLL("./xxx.dll")  # 替换为实际库路径
except Exception as e:
    print(f"加载动态库失败: {str(e)}")
    sys.exit(1)

# 严格设置函数原型
sdk.Init.argtypes = [c_char_p, c_ushort, OnPayResult]
sdk.Init.restype = c_size_t

# 保持回调函数引用防止GC
_callback_ref = None

def init_sdk():
    global _callback_ref
    
    # 包装回调函数
    def py_pay_result(p_result):
        if not p_result:
            print("收到空指针!")
            return
        
        try:
            # 安全访问结构体内容
            result = p_result.contents
            # 处理可能为NULL的字符串
            err_code = result.errCode.decode() if result.errCode else ""
            err_info = result.errInfo.decode() if result.errInfo else ""
            print(f"错误码: {err_code}, 错误信息: {err_info}")
        except Exception as e:
            print(f"处理回调时发生异常: {str(e)}")

    # 转换为C回调并保持引用
    _callback_ref = OnPayResult(py_pay_result)
    
    # 调用初始化
    ip = b"127.0.0.1"
    port = 443
    return sdk.Init(ip, port, _callback_ref)

if __name__ == "__main__":
    init_sdk()
    print("SDK初始化完成,等待回调...")
    
    # 保持程序运行(根据实际需求调整)
    while True:
        pass

这里重要的点是回调函数中,结构体指针是C代码分配的内存,与python有区别,C的结构体中的字段并没有各种方法和属性,需要注意转换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿捏利

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值