2016-10-19 4 views
0

많은 문서, 예제 및 StackOverflow 주제를 읽었지 만 여전히 작동하지 않습니다! 저는 C++ COM 객체에 파이썬 인터페이스를 작성하고 있습니다. 내가 이것을 한 것은 처음이 아니다. 과거에는 comtypes를 사용하여 개별 인터페이스 포인터를 얻고 COM 클래스를 전달했지만 인터페이스 포인터 배열에 포인터를 전달해야합니다.파이썬에서 C++로 COM 포인터 배열을 전달합니다.

내가 전화를해야하는 COM 인터페이스 다음 attributeExportLayers 인수 IFeatureLayer 포인터의 null로 끝나는 C 배열에 대한 포인터 될 것으로 예상된다

STDMETHOD(ExportGeopackage)([in] IMap* pMap, 
          [in] imageFormatType imageFormat, 
          [in] long imageQuality, 
          [in] long zoomMin, 
          [in] long zoomMax, 
          [in] IFeatureLayer** attributeExportLayers, 
          [in] BSTR title, 
          [in] BSTR description, 
          [in] BSTR saveToPath, 
          [in] ITrackCancel* pTrackCancel); 

. ExportGeopackage()는 이미 C++ 클라이언트에서 테스트되었습니다. 첫 번째 Python 클라이언트를 작성하고 있습니다.

파이썬

: 파이썬 exportLayer와 포인터 변수의 내용을 비교 덤프

# append a null pointer to the list of comtypes IFeatureLayer pointers 
exportLayers.append(comtypes.cast(0, comtypes.POINTER(esriCarto.IFeatureLayer))) 
# create ctypes array and populate 
PointerArray = ctypes.c_void_p * len(exportLayers) 
pointers = PointerArray() 
for i in range(len(exportLayers)): 
    pointers[i] = exportLayers[i] 

# export is comtypes interface pointer acquired earlier 
export.ExportGeopackage(map, format, quality, min, max, 
         ctypes.cast(pointers, ctypes.POINTER(esriCarto.IFeatureLayer)), 
         title, desc, geopackage_path, 0) 

포인터 값이 성공적으로 후자를 전자로 전달되는 나타낸다. 이 포인터에 대한 Python 테스트는 성공적입니다. 그러나 ExportGeopackage()로 디버깅 할 때 attributeExportLayers가 가리키는 메모리는 예상되는 배열의 IFeatureLayer 포인터와 유사하지 않습니다. 그것은 하나의 포인터 (잘못된 위치를 가리키는)와 null 포인터의 긴 문자열이 뒤 따르는 것처럼 보입니다. 아마도 파이썬 포인터 변수가 이미 가비지 수집되었다고 생각하여 ExportGeopackage()를 호출 한 후 포인터에 대한 참조를 추가했습니다. 이것은 아무런 효과가 없었다.

나는 간접비의 추가 수준을 삽입하거나 불충분 한 간접 참조를 삽입하고 있습니까? 나는 신비화되었다.

TIA (도움말) (또는 추측). Alan

답변

0

다시 한번 자신의 질문에 대답합니다. 필요한 수준을 넘어 간접적 인 추가 수준이 도입됩니다. 분명히 C에서 캐스팅과 달리, ctypes.cast 실제로 첫 번째 인수의 주소를 걸립니다.

변경 :)

PointerArray = comtypes.POINTER(esriCarto.IFeatureLayer) * len(exportLayers) 

그리고 ExportGeopackage (호출에 ctypes.cast의 사용을 제거 :

PointerArray = ctypes.c_void_p * len(exportLayers) 

으로

export.ExportGeopackage(map, format, quality, min, max, 
         pointers, 
         title, desc, geopackage_path, 0)