2016-10-19 3 views
0

Я читал много документов, примеров и StackOverflow, но все равно это не работает! Я пишу интерфейс Python для своих COM-объектов C++. Это не первый раз, когда я это сделал. В прошлом я успешно использовал comtypes для получения отдельных указателей интерфейса и передал им свои COM-классы, но на этот раз мне нужно передать указатель на массив указателей интерфейса.Передача массива COM-указателей от Python до C++

COM-интерфейс нужно вызвать:

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); 

attributeExportLayers аргумент как ожидается, будет указатель на нуль-терминатором C массив указателей IFeatureLayer. ExportGeopackage() уже был протестирован с клиентами C++. Я пишу первый клиент Python.

В Python:

# 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 отвалов содержания exportLayer и указатели переменных показывает значение указателя успешно передается от первого к последнему. Тесты Python этих указателей успешны. Однако, когда я отлаживаю ExportGeopackage(), память, на которую указывает атрибутExportLayers, не имеет сходства с ожидаемым массивом указателей IFeatureLayer. Он выглядит как один указатель (указывающий на неправильное место), за которым следует длинная строка нулевых указателей. Думая, что, возможно, переменная указателей на Python уже была собрана мусором, я добавил ссылку на указатели после вызова ExportGeopackage(). Это не имело никакого значения.

Я как-то вставляю дополнительный уровень косвенности, или не хватает косвенности? Я озадачен.

TIA за любую помощь (или догадки). Alan

ответ

0

Еще раз, отвечая на мой собственный вопрос. Существует дополнительный уровень косвенности, вводимый за пределы того, что требуется. По-видимому, в отличие от актера в C, ctypes.cast фактически принимает адрес первого аргумента.

Изменение:

PointerArray = ctypes.c_void_p * len(exportLayers) 

To:

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

и исключить использование ctypes.cast в вызове ExportGeopackage():

export.ExportGeopackage(map, format, quality, min, max, 
         pointers, 
         title, desc, geopackage_path, 0) 
Смежные вопросы