簡體   English   中英

用 Python 從 C++ dll 返回數據

[英]Return data from c++ dll with Python

我正在為 3M 文檔掃描儀的接口編程。

我正在調用一個名為MMMReader_GetData的函數

MMMReaderErrorCode MMMReader_GetData(MMMReaderDataType aDataType,void* DataPtr,int* aDataLen);

描述:

從文檔中讀取數據項后,可以通過此 API 獲取該數據項。 aDataPtr 參數中提供的緩沖區將與數據一起寫入,並且 aDataLen 更新為數據的長度。

問題是如何創建void* DataPrt以及如何獲取數據?

我試過了:

from ctypes import *
lib=cdll.LoadLibrary('MMMReaderHighLevelAPI.dll')
CD_CODELINE = 0
aDataLen = c_int()
aDataPtr = c_void_p()
index= c_int(0)

r = lib.MMMReader_GetData(CD_CODELINE,byref(aDataPtr),byref(aDataLen),index)

aDataLen總是返回一個值,但aDataPtr返回None

您的代碼有幾個問題:

  1. 您需要分配aDataPtr指向的緩沖區。
  2. 您需要在aDataLen傳遞緩沖區長度。 根據[1],如果緩沖區不夠大, MMMReader_GetData將根據需要重新分配。
  3. 您應該直接傳遞aDataPtr ,而不是byref
  4. 您正在根據您提供的MMMReader_GetData的方法描述符向方法( index參數)傳遞一個額外的參數。

請嘗試以下操作:

import ctypes

lib = ctypes.cdll.LoadLibrary('MMMReaderHighLevelAPI.dll')

CD_CODELINE = 0
aDataLen = ctypes.c_int(1024)
aDataPtr = ctypes.create_string_buffer(aDataLen.value)

err = lib.MMMReader_GetData(CD_CODELINE, aDataPtr, ctype.byref(aDataLen))

然后您可以將緩沖區的內容作為常規字符數組讀取。 實際長度在aDataLen返回。

[1] 3M頁面閱讀器程序員指南: https : //wenku.baidu.com/view/1a16b6d97f1922791688e80b.html

您需要做的是分配一個“緩沖區”。 緩沖區的地址將作為 void* 參數傳遞,緩沖區的大小(以字節為單位)將作為aDataLen參數傳遞。 然后函數會將它的數據放入你給它的緩沖區中,然后你可以從緩沖區中讀回數據。

在 C 或 C++ 中,您將使用malloc或類似的東西來創建緩沖區。 使用ctypes ,可以使用ctypes.create_string_buffer制作一定長度的緩沖區,然后將緩沖區和長度傳遞給函數。 然后一旦函數填充它,您就可以從您創建的緩沖區中讀取數據,它的工作方式類似於帶有[]len()的字符列表。

使用ctypes ,最好定義參數類型和返回值以進行更好的錯誤檢查,並且聲明指針類型在 64 位系統上尤其重要。

from ctypes import *

MMMReaderErrorCode = c_int  # Set to an appropriate type
MMMReaderDataType = c_int   # ditto...

lib = CDLL('MMMReaderHighLevelAPI')
lib.MMMReader_GetData.argtypes = MMMReaderDataType,c_void_p,POINTER(c_int)
lib.MMMReader_GetData.restype = MMMReaderErrorCode

CD_CODELINE = 0

# Make sure to pass in the original buffer size.
# Assumption: the API should update it on return with the actual size used (or needed)
# and will probably return an error code if the buffer is not large enough.
aDataLen = c_int(256)

# Allocate a writable buffer of the correct size.
aDataPtr = create_string_buffer(aDataLen.value)

# aDataPtr is already a pointer, so no need to pass it by reference,
# but aDataLen is a reference so the value can be updated.
r = lib.MMMReader_GetData(CD_CODELINE,aDataPtr,byref(aDataLen))

返回時,您可以通過字符串切片僅訪問緩沖區的返回部分,例如:

>>> from ctypes import *
>>> aDataLen = c_int(10)
>>> aDataPtr = create_string_buffer(aDataLen.value)
>>> aDataPtr.raw
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
>>> aDataLen.value = 5        # Value gets updated
>>> aDataPtr[:aDataLen.value] # Get the valid portion of buffer
'\x00\x00\x00\x00\x00'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM