這個專欄好久沒有更新了,主要是坑開的有點大,也不知道怎么填,涉及到的開發語言比較多,寫起來比較累,需要看的人其實并不多,只能說,慢慢填吧,中間肯定還會插很多別的東西,更新頻率自己也不知道。
上一次說了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 = Nonedef 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 = 2order.pstGoodsInfo = cast(goods_array, POINTER(stGoodsInfo)) # 關鍵指針轉換# 調用C接口(傳遞結構體指針)lib.PalmPay(byref(order))if __name__ == "__main__":main()