2013-08-09 3 views
0

파이썬에서 DLL의 int 배열에 액세스하려고합니다. ctypes 문서 페이지의 지침을 따르고 있지만 null 포인터 액세스 예외가 발생합니다. 내 코드는 다음과 같습니다Python에서 DLL의 배열에 액세스

if __name__ == "__main__": 
    cur_dir = sys.path[0] 
    os.chdir(cur_dir) 
    api = CDLL("PCIE_API") 
    PciAgentIndex=POINTER(c_uint32).in_dll(api, "PciAgentIndex") 
    print(PciAgentIndex) 
    print(PciAgentIndex[0]) 

내가 얻을 :

내가 마지막 줄을 인쇄
ValueError: NULL pointer access 

. 이클립스 디버거를 통해이 코드를 실행하고 PciAgentIndex의 콘텐츠 속성을 검사 할 때

내가 얻을 : 내가 잘못 뭐하는 거지

str: Traceback (most recent call last): 
    File "C:\Program Files\eclipse\plugins\org.python.pydev_2.7.5.2013052819\pysrc\pydevd_resolver.py", line 182, in _getPyDictionary 
    attr = getattr(var, n) 
ValueError: NULL pointer access 

? 나는 Windows에서 파이썬 3.3.2를 사용하고있다.

답변

3

포인터와 배열의 차이점을 명확히하기 위해 comp.lang.c FAQ 질문 6.2 : But I heard that char a[] was identical to char *a을 읽으십시오.

DLL의 데이터에서 포인터를 만들고 있습니다. 데이터는 4 바이트 (32 비트 Python) 또는 8 바이트 (64 비트 Python)로 시작됩니다. 대신 배열을 사용하여

# for a length n array 
PciAgentIndex = (c_uint32 * n).in_dll(api, "PciAgentIndex") 

는 또한, 함수 포인터를 캐스팅 할 수 있습니다 포인터를 원하는 경우 :

PciAgentIndex = cast(api.PciAgentIndex, POINTER(c_uint32)) 

A는 데이터 객체가 관련 C에 대한 버퍼에 대한 포인터를 가지고하는 ctypes 데이터. 포인터 용 버퍼는 파이썬이 32 비트인지 64 비트인지에 따라 4 바이트 또는 8 바이트입니다. 배열의 버퍼는 요소 크기와 길이를 곱한 값입니다. in_dll은 DLL의 데이터 범위 (복사본이 아닌)를 버퍼로 사용하여 인스턴스를 만드는 클래스 메서드입니다.

+0

감사합니다. 이제 배열과 함께 작동합니다! 어쨌든, 나는이 논리 뒤에있는 논리를 이해하지 못했습니다. 얼마나 많은 null 바이트가 있는지 모르지만 그 이유는 무엇입니까? –

+0

감사합니다, eryksun, 당신은 다시 나를 도왔습니다 :) 어쨌든, 내 파이썬은 64 비트이지만 C 포인터는 64 비트 와이드 때마다? 포인터에서 8 바이트가 널이라고 말하면, 포인터는 64 비트보다 넓어야합니까? –

+0

죄송합니다. 계속 질문하겠습니다.하지만 틀린 것이 아니라면 PciAgentIndex는 실제로 배열의 첫 번째 요소에 대한 포인터입니다. 너비는 64 비트 여야합니다. 내 예제에서는 dll PciAgentIndex 주소로 "파이썬 포인터"초기화 해요. 왜 이것이 작동하지 않습니까? "파이썬 포인터"와 내 보낸 주소는 모두 64 비트 폭이어야합니다. "파이썬 포인터"는 null이 아니어야합니까? –