2012-01-19 2 views
0

私はctypesを使ってPythonにVisual C++ 6アプリケーションを移植しています。 同じWindowsライブラリdllを使用します。私はWindowsフォームをPythonアプリケーションに移植するだけです。は、python ctypes.Structureに構造体タグ付け規則がありますか?

と私はpythonでDLLに、CPP構造を送っていたとき、私はstuckedです。

私は、構造体differecesで解決策を見つけることを試みました。 cppコードからは、struct tagging(tagTest)がありますが、Pythonコードには同等のものはありません。そのための解決策はありますか?

これは私が移植したいcppです。

======================== cppの一部==================== ============

BOOL CSMessage(HWND hWnd, const char* string1, const char* string2, const char* ltagTest, int structlen); 

typedef struct tagTest 
{ 
    char item1      [ 8]; char _item1; 
    char item2      [ 1]; char _item2; 
} TcTest, *LPTest; 

void Initiator() 
{ 
    TcTest ctest ={0}; 
    memset(&ctest,0x20,sizeof TcTest); 
    move(ctest.item1,"TESTSTRI"); 
    move(ctest.item2,"1"); 

    mhandler.CSMessage(GetSafeHwnd(),"String","Call",(char*)&ctest,sizeof TcTest); 
} 

========================= pythonpart ===== =======================

csMessageProto=ctypes.WINFUNCTYPE(BOOL, HWND, c_char_p, c_char_p, c_char_p, c_int) 
csMessageParams=((1,"hWnd",0),(1,"string1",0),(1,"string2",0),(1,"ltagTest",0),(1,"structlen",0)) 
CSMessage=csMessageProto(("CSMessage",testDll), csMessageParams) 

class tagTest(ctypes.Structure): 
    _fields_ = [ 
     ('item1', c_char*8),('_item1', c_char), 
     ('item2', c_char*1),('_item2', c_char) 
    ] 
PtagTest=ctypes.POINTER(tagTest) 

utestblock=tagTest() 
utestblock.item1=str("TESTSTRI") 
utestblock.item2=str(1) 

CSMessage(hwnd, "String", "Call", ctypes.byref(utestblock), ctypes.sizeof(utestblock)); 

改訂履歴

  1. はの宣言を追加しますDLL関数のcppと@avl_sweden提案

=====================結果と改訂のpython

  • ========両方========================

    @ avl_swedenの提案の後、 テストの後、エラーmsgはこれです。

    ctypes.ArgumentError: argument 4: <type 'exceptions.TypeError'>: wrong type 
    

    及びタイプ

    print "Is Type : "+str(ctypes.byref(utestblock)) 
    
    Is Type : <cparam 'P' (023e5968)> 
    

    ため================================ =========================

    ので、それはだが種類はDEFとインスタンスが異なっているように見えます。

    Pythonコードの最初の行に

    1: csMessageProto=ctypes.WINFUNCTYPE(BOOL, HWND, c_char_p, c_char_p, c_char_p, c_int) 
    

    第c_char_pは差異と一致する

    16: CSMessage(hwnd, "String", "Call", ctypes.byref(utestblock), ctypes.sizeof(utestblock)); 
    

    に一致されていません。

    Iは

    1: csMessageProto=ctypes.WINFUNCTYPE(BOOL, HWND, c_char_p, PtagTest, c_char_p, c_int) 
    

    、コードエラーが返されないようにコードを変更しました。しかし、それが送信されている場合私は見つけることができません。 dllからのリターンはありませんでした。

    これは適切な解決策だと思いますか?

    ============================================== =======================================

    私がテストされている、それはそうですそれは正しい解決策です。

    もう一度ありがとうございます。

  • +0

    はどこでもそれの定義はありません。 – martineau

    +0

    見ていただきありがとうございます。それは間違っていた。 – nikescar

    +0

    それはPOINTER(tagTest)でした。私はスペルミスがありました。 – nikescar

    答えて

    0

    私はここで間違っ4つの物事を参照してください。

    まず、あなたのPythonの構造定義は、C-コードスニペットに1と一致していません。あなたがCSMessage関数へのポインタへのポインタを送信していることが分かります。

    あなたが試みることができる:

    utestblock=tagTest() 
    utestblock.item1=str("TESTSTRI") 
    utestblock.item2=str(1) 
    
    loadeddll.CSMessage(hwnd, "String", "Call", ctypes.byref(utestblock), 
            ctypes.sizeof(utestblock)) 
    

    を第三の問題はそれほど深刻であり、これは、文字列"TESTSTRING"が8バイトに収まらないということです。

    私が見る第4の問題は、デフォルトパラメータの種類が間違っていることです。

    は、代わりにこれを試してください:あなたは `tagcTest`が、私と呼ばれるものを参照してくださいあなたのPythonコードで

    csMessageParams=((1, "hWnd", 0), (1, "string1", ""), (1, "string2", ""), 
           (1, "ltagTest", ""), (1, "structlen", 0)) 
    
    +0

    ありがとうございます。 (1、 "文字列1"、 "")、(1、 "文字列2"、 ""、(1、 "ltagTest"、 "")、(1、 "hWnd"、0) csMessageParams =((1、 "hWnd"、0)、(1、 "string1"、 "")、(1、 "string2"、 "")、(1、 "structlen"、0) "ltagTest"、 "")、(1、 "structlen"、0)) 'は同じ結果を返します。私はあなたの方法をテストし、質問を改訂しました。 – nikescar