Tôi đang cố gắng gọi một DLL từ Python. DLL được viết thẳng C và không có gì phức tạp về nó. Đây là loại điều mà ctypes chính xác thực hiện. Tuy nhiên tôi gặp khó khăn khi nhận được các giá trị chính xác trong một cấu trúc trả về từ các cuộc gọi hàm DLL. Giá trị đầu tiên trong cấu trúc đã truyền được trả về chính xác nhưng các giá trị khác thì không.Python ctypes không trả lại chính xác một số giá trị được chuyển bởi tham chiếu
Mã đọc nhiều thư từ bộ đệm trong bộ nhớ. Nó sử dụng một mô hình mã hóa ReadFirst()/ReadNext(). Có một cấu trúc "thông báo hiện tại" được truyền vào để theo dõi trạng thái.
Đây là struct C chứa ReadFirst hiện tại()/ReadNext() nhà nước ...
typedef struct
{
unsigned int uMsgNum;
uint32_t ulCurrOffset;
uint32_t ulDataLen;
Su1553F1_ChanSpec * psuChanSpec;
Su1553F1_Header * psu1553Hdr;
SuCmdWordU * psuCmdWord1;
SuCmdWordU * psuCmdWord2;
uint16_t * puStatWord1;
uint16_t * puStatWord2;
uint16_t uWordCnt;
uint16_t * pauData;
} Su1553F1_CurrMsg;
Đây là ctypes struct đối viết bằng ctypes ...
class CurrMsg_1553F1(ctypes.Structure):
''' Data structure for the current 1553 message info structure '''
_pack_ = 1
_fields_ = [("MsgNum", ctypes.c_uint32),
("CurrOffset", ctypes.c_uint32),
("DataLen", ctypes.c_uint32),
("pChanSpec", ctypes.POINTER(ChanSpec_1553F1)),
("p1553Hdr", ctypes.c_void_p),
("pCmdWord1", ctypes.POINTER(CmdWord)),
("pCmdWord2", ctypes.POINTER(CmdWord)),
("pStatWord1", ctypes.c_void_p),
("pStatWord2", ctypes.c_void_p),
("WordCnt", ctypes.c_uint16),
("pData", ctypes.c_void_p)]
Tôi sẽ cung cấp thêm chi tiết bên dưới, nhưng điểm mấu chốt của vấn đề là các cuộc gọi đến ReadFirst()/ReadNext() trả lại chính xác các giá trị cho MsgNum nhưng các giá trị khác là rác. Đây là một đầu ra mẫu ...
MsgNum 0 CurrOffset 40912728 DataLen 40912732 Messages = 3664897
MsgNum 1 CurrOffset 40912728 DataLen 40912748 Messages = 60417
MsgNum 2 CurrOffset 40912728 DataLen 40912748 Messages = 60417
etc.
MsgNum là đúng và ReadFirst()/ReadNext() lặp chính xác số lần. Tuy nhiên, các giá trị cho CurrOffset và DataLen là rác. (Giá trị tin nhắn được dereferenced từ con trỏ đến bộ nhớ khác.Tôi không nghĩ rằng tôi có quyền nhưng tôi sẽ phải lưu rằng một cho đến khi tôi nhận được công cụ này khác cố định. có lẽ là sai cũng có.)
Dưới đây là các giao diện cho các chức năng ...
EnI106Status enI106_Decode_First1553F1
(SuI106Ch10Header * psuHeader,
void * pvBuff,
Su1553F1_CurrMsg * psuMsg);
EnI106Status enI106_Decode_Next1553F1
(Su1553F1_CurrMsg * psuMsg);
những chức năng DLL được gọi (cùng với báo cáo gỡ lỗi in) bằng cách ...
def __init__(self, PacketIO):
self.CurrMsg = CurrMsg_1553F1()
def Decode_First1553F1(self):
Status = self.PacketIO._IrigDataDll.enI106_Decode_First1553F1(ctypes.byref(self.PacketIO.Header), ctypes.byref(self.PacketIO.Buffer), ctypes.byref(self.CurrMsg))
print "MsgNum %d CurrOffset %d DataLen %d Messages = %d" % \
(Decode1553.CurrMsg.MsgNum, Decode1553.CurrMsg.CurrOffset, Decode1553.CurrMsg.DataLen, Decode1553.CurrMsg.pChanSpec.contents.MsgCnt)
return Status
def Decode_Next1553F1(self):
Status = self.PacketIO._IrigDataDll.enI106_Decode_Next1553F1(ctypes.byref(self.CurrMsg))
print "MsgNum %d CurrOffset %d DataLen %d Messages = %d" % \
(Decode1553.CurrMsg.MsgNum, Decode1553.CurrMsg.CurrOffset, Decode1553.CurrMsg.DataLen, Decode1553.CurrMsg.pChanSpec.contents.MsgCnt)
return Status
DLL C được biên dịch theo Visual Studio 2005. Tôi đã sử dụng DLL này rất nhiều với các chương trình C và C++ .NET khác nhau mà không gặp vấn đề gì.
Tôi đã sử dụng các mẫu và cấu trúc để trả về các giá trị trong mã khác và dường như nó hoạt động tốt. Kể từ khi giá trị đầu tiên trong cấu trúc là OK nhưng các giá trị tiếp theo là cách này "cảm thấy" như một vấn đề liên kết dữ liệu. Tôi đã đặt gói = 1 trong cấu trúc ctypes và đã đặt căn chỉnh byte trong mã DLL đã biên dịch. Tôi đã thực hiện sizeof bản in của mỗi cấu trúc và xác minh họ là kích thước dự kiến.
Tôi đã đánh đầu vào tường trên cái này một lúc và không có ý tưởng. Bạn có suy nghĩ gì về việc thử tiếp theo không?
Trong đoạn mã Python, bạn vượt qua ByRef (self.CurrMsg), nhưng bạn in các lĩnh vực từ Decode1553.CurrMsg. Không nên bạn in các lĩnh vực từ self.CurrMsg thay vào đó? –