2011-08-10 4 views
1

は、私は次のような構造のpython - DLLのヘッダファイルに構造OUT引数

typedef struct USMC_Devices_st{ 
DWORD NOD;   // Number of the devices ready to work 

char **Serial;  // Array of 16 byte ASCII strings 
char **Version;  // Array of 4 byte ASCII strings 
} USMC_Devices;   // Structure representing connected devices 

を持っている私は、DLL関数を呼び出すしたいと思います: DWORD USMC_Init(USMC_Devices &筋力を) ;

私はこれを試してみました:

class USMCDevices(Structure): 
    _fields_ = [("NOD", c_long), 
      ("Serial", c_char_p), 
      ("Version", c_char_p)] 

usmc = cdll.USMCDLL #this is the dll file 
init = usmc.USMC_Init 
init.restype = c_int32; # return type 
init.argtypes = [USMCDevices]; # argument 
dev = USMCDevices() 
init(dev) 

私はここにエラーが発生します。私は問題が "シリアル"と "バージョン"両方のNOD(デバイスの数)に対応する配列であると思います。

どのようにこの問題を解決するためのアイデアですか?

本当にありがとうございます!

答えて

2

char **ポインタにはPOINTER(c_char_p)を使用してください。インデックスSerialまたはVersionは、指定されたヌル終了文字列のPython文字列を作成します。 NOD - 1を超えて配列内のインデックスを作成すると、ガベージ値が生成されるか、インタプリタがクラッシュすることに注意してください。

C:

#include <windows.h> 

typedef struct USMC_Devices_st { 
    DWORD NOD;  // Number of the devices ready to work 
    char **Serial; // Array of 16 byte ASCII strings 
    char **Version; // Array of 4 byte ASCII strings 
} USMC_Devices; 

char *Serial[] = {"000000000000001", "000000000000002"}; 
char *Version[] = {"001", "002"}; 

__declspec(dllexport) DWORD USMC_Init(USMC_Devices *devices) { 

    devices->NOD = 2; 
    devices->Serial = Serial; 
    devices->Version = Version; 

    return 0; 
} 

// build: cl usmcdll.c /LD 

のPython:

import ctypes 
from ctypes import wintypes 

class USMCDevices(ctypes.Structure): 
    _fields_ = [("NOD", wintypes.DWORD), 
       ("Serial", ctypes.POINTER(ctypes.c_char_p)), 
       ("Version", ctypes.POINTER(ctypes.c_char_p))] 

usmc = ctypes.cdll.USMCDLL 
init = usmc.USMC_Init 
init.restype = wintypes.DWORD 
init.argtypes = [ctypes.POINTER(USMCDevices)] 
dev = USMCDevices() 
init(ctypes.byref(dev)) 

devices = [dev.Serial[i] + b':' + dev.Version[i] 
      for i in range(dev.NOD)] 
print('\n'.join(d.decode('ascii') for d in devices)) 

出力:

000000000000001:001 
000000000000002:002 
+0

は、非常にありがとうございました!!! あなたは私を助けてくれました! しかし、私はまだ問題があります。 dev.Serial [i] .valueのポインタが正しい位置を指していません。例:私はdev.Serial [2] .valueで適切なシリアル文字列を取得しますが、インデックスi = 0またはi = 1では、間違ったデータが返されます(配列のサイズは2つだけです)。何か案は??? – jankos

+0

さらに構造を変更して最初のバージョンを定義してからシリアルを定義すると、文字列はdev.Serial [1]にあり、他のすべてのインデックスは間違った結果を返します。私は本当にヒントを感謝します! – jankos

+0

ありがとうございます。それは今働く!他の機能も現在動作しています。あなたは私をたくさん助けてくれました!ありがとう、私はあなたに良い一日を祈っています! – jankos

関連する問題