2011-08-10 4 views
1

나는 다음과 같은 구조를파이썬이 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의 헤더 파일에서 나는 DLL 함수를 호출하고 싶습니다 : DWORD의 USMC_Init을 (USMC_Devices & str을) ;

은 이걸로 시도 :

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 인덱싱은 주어진 Null 종료 문자열에 대한 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 

파이썬 :

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

관련 문제