高级语言调用C接口(四)结构体(2)-Python

这个专栏好久没有更新了,主要是坑开的有点大,也不知道怎么填,涉及到的开发语言比较多,写起来比较累,需要看的人其实并不多,只能说,慢慢填吧,中间肯定还会插很多别的东西,更新频率自己也不知道。

上一次说了Java和C#调用C接口传递结构体,今天来说一下Python。由于鸿蒙并不需要在arkts层真正的定义结构体,Napi层可以通过Json转结构体的方式来实现,还没想好怎么去举例子,下次再说吧。

Python这种脚本语言并没有结构体的概念,所以我们要用到Python的ctypes包中的Structure。

和Java、C#一样,由于高级语言的结构与C的结构体并不完全一样,高级语言的类包含方法,而C的结构体是定义即所见,所以C接口直接调用高级语言的结构体数组地址时,会崩溃,Python也和C#、Java一样,定义为数组并赋值,再将数组转换为连续内存。

from ctypes import *
import sys

# 定义结构体(需与C头文件完全一致)
class stGoodsInfo(Structure):
    _fields_ = [
        ("goodsId", c_char_p),
        ("goodsName", c_char_p),
        ("quantity", c_char_p),
        ("price", c_char_p),
        ("goodsCategory", c_char_p),
        ("body", c_char_p),
        ("discount", c_char_p),
        ("unit", c_char_p)
    ]

class stOrderInfo(Structure):
    _fields_ = [
        ("merOrderId", c_char_p),
        ("srcReserve", c_char_p),
        ("orderDesc", c_char_p),
        ("totalAmount", c_char_p),
        ("goodsNum", c_int),
        ("pstGoodsInfo", POINTER(stGoodsInfo)),
        ("attachedData", c_char_p)
    ]

# 加载动态库(示例名称,需替换实际库路径)
lib = CDLL("XXX.so")  # Linux/Mac
# lib = WinDLL("XXX.dll")  # Windows

# 定义函数原型
lib.PalmPay.argtypes = [POINTER(stOrderInfo)]
lib.PalmPay.restype = None

def main():
    # 创建商品数组(保持内存连续)
    goods_array = (stGoodsInfo * 2)()

    # 填充第一个商品
    goods_array[0] = stGoodsInfo(
        goodsId=b"SDGOOD000001",
        goodsName="哇哈哈矿泉水".encode('utf-8'),
        quantity=b"2",
        price=b"2.00",
        goodsCategory="食品饮料".encode('utf-8'),
        body="饮料".encode('utf-8'),
        discount=b"0",
        unit="瓶".encode('utf-8')
    )

    # 填充第二个商品
    goods_array[1] = stGoodsInfo(
        goodsId=b"SDGOOD000002",
        goodsName="百岁山矿泉水".encode('utf-8'),
        quantity=b"2",
        price=b"3.00",
        goodsCategory="食品饮料".encode('utf-8'),
        body="饮料".encode('utf-8'),
        discount=b"0",
        unit="瓶".encode('utf-8')
    )

    # 创建订单结构体
    order = stOrderInfo()
    order.merOrderId = b"SD000000000000001"
    order.srcReserve = b"aaaaaaaaaaaaaa"
    order.orderDesc = b"Test"
    order.totalAmount = b"10.00"
    order.attachedData = b"attachedData test"
    order.goodsNum = 2
    order.pstGoodsInfo = cast(goods_array, POINTER(stGoodsInfo))  # 关键指针转换

    # 调用C接口(传递结构体指针)
    lib.PalmPay(byref(order))

if __name__ == "__main__":
    main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿捏利

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

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

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

打赏作者

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

抵扣说明:

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

余额充值