私はPythonからDLLを呼び出そうとしています。 DLLはまっすぐなC言語で書かれており、それについては何もひどく複雑ではありません。これはctypesが正確に作られたものです。しかし、私はDLLの関数呼び出しから返された構造体内で正しい値を得ることに問題があります。渡された構造体の最初の値は正しく返されますが、他の値は返されません。Python ctypesが参照渡しの値を正しく返さない
このコードは、メモリ内のバッファから複数のメッセージを読み取ります。 ReadFirst()/ ReadNext()コーディングパラダイムを使用します。状態を追跡するために渡される "現在のメッセージ"構造体があります。ここ
が現在ReadFirst()/ READNEXT()状態を保持している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;
はctypesのに書き込まれた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)]
以下で詳細を説明しますが、ReadFirst()/ ReadNext()の呼び出しはMsgNumの値を正しく返しますが、他の値はガベージです。ここではサンプル出力は...
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が正しいとReadFirst()/ READNEXT()は、正しい回数を反復しています。ただし、CurrOffset、DataLenの値はガベージです。 (メッセージ値は他のメモリへのポインタから逆参照されていますが、私はまだそうは思いませんが、他のものを修正するまでその値を保存する必要があります。また、おそらく間違っている。)
EnI106Status enI106_Decode_First1553F1
(SuI106Ch10Header * psuHeader,
void * pvBuff,
Su1553F1_CurrMsg * psuMsg);
EnI106Status enI106_Decode_Next1553F1
(Su1553F1_CurrMsg * psuMsg);
これらのDLL関数
は()によるデバッグprint文と一緒に呼び出されます ここ機能のためのインタフェースである... ...
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
Visual Studio 2005の下でC DLLがコンパイルされます。私はこのDLLをたくさん使用しましたさまざまなCおよびC++ .NETプログラムに問題はありません。
私はctypesと構造体を使用して他のコードの値を返しましたが、うまくいきました。構造体の最初の値はOKですが、後続の値は途切れているため、データの整列の問題のように感じられます。私はパック = 1をctypes構造体に設定し、コンパイルされたDLLコードにバイトアライメントを設定しました。私は各構造体のsizeof printoutを行い、それらが予想されるサイズであることを確認しました。
私はしばらくの間この壁に頭を打ち、アイデアがありません。次は何をしようと思っていますか?
をコーディングすることができるはずです、あなたは(self.CurrMsg)のByRef渡していますが、Decode1553.CurrMsgからフィールドを印刷します。代わりにself.CurrMsgからフィールドを印刷するべきではありませんか? –