当前位置: 首页 > news >正文

高级语言调用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()

相关文章:

  • 如何在本地修改 Git 项目的远程仓库地址
  • 智算启新篇 安全筑新基 ——中国移动举办智算基础设施及安全分论坛
  • C++ 智能指针底层逻辑揭秘:优化内存管理的核心技术解读
  • Java 中常见的数据结构
  • 3、组件:魔法傀儡的诞生——React 19 组件化开发全解析
  • 【Python爬虫】详细入门指南
  • UNet深度学习实战遥感航拍图像语义分割
  • Java雪花算法
  • RabbitMQ的应用
  • mysql和mongodb
  • React 之 Redux 第三十二节 Redux 常用API及HOOKS,以及Redux Toolkit核心API使用详解
  • 62. 评论日记
  • java 实现文件编码检测的多种方式
  • Podman技术深度解剖:架构、原理与核心特性解析
  • cocos Spine资源及加载
  • JavaScript Map 对象深度解剖
  • HarmonyOS 第2章 Ability的开发,鸿蒙HarmonyOS 应用开发入门
  • 开源FMC 4路千兆网模块
  • Git 基本使用
  • 塑料瓶识别分割数据集labelme格式976张1类别
  • 第1现场 | 美国称将取消制裁,对叙利亚意味着什么
  • 中东睿评|特朗普中东三国行:喧嚣的形式与空洞的实质
  • 中国-拉共体成员国重点领域合作共同行动计划(2025-2027)
  • 京东美团饿了么等外卖平台被约谈
  • 金价大跌!足金饰品每克一夜便宜14元,涨势是否已终结?
  • 张笑宇:物质极大丰富之后,我们该怎么办?