Как передать массив структур (содержащих std:string или BSTR) из ATL в C#. Безопасный массив? Вариант?

У меня есть COM-объект ATL, который я использую из С#. На данный момент интерфейс выглядит так:

interface ICHASCom : IDispatch{
    [id(1), helpstring("method Start")] HRESULT Start([in] BSTR name, [out,retval] VARIANT_BOOL* result);
...
    [id(4), helpstring("method GetCount")] HRESULT GetCount([out,retval] LONG* numPorts);
...

    [id(7), helpstring("method EnableLogging")] HRESULT EnableLogging([in] VARIANT_BOOL enableLogging);
};

То есть это очень простой интерфейс. У меня также есть некоторые события, которые я тоже отправляю обратно. Теперь я хотел бы добавить кое-что к интерфейсу. В ATL у меня есть некоторые результаты, которые в настоящее время являются структурами и выглядят так: struct REPORT_LINE { string createDate; идентификатор строки; сводка строки; }; Все члены структуры являются std::string. У меня есть их массив, который мне нужен, чтобы вернуться к С#. Как лучше всего это сделать?

Я подозреваю, что кто-то скажет: «Эй, вы не можете просто отправить std::string через COM вот так. Если да, то хорошо, но как лучше всего модифицировать структуру? Изменить std::string на BSTR? И как мне это сделать: 1) Настроить IDL для передачи массива структур (структуры с BSTR или std::string) 2) Если я должен использовать SAFEARRAYS, как мне заполнить SAFEARRAYS структурами.

Я не знаком с COM, за исключением использования с простыми типами.


person Dave    schedule 05.05.2010    source источник


Ответы (1)


определенная пользователем структура несовместима с интерфейсом автоматизации. Вы, вероятно, можете разработать вложенный массив или двумерный безопасный массив BSTR, но более удобным решением будет обернуть структуру как объект автоматизации с 3 свойствами, а затем обернуть массив как коллекцию с перечислителем.

Ни IDL, ни автоматизация не определяют выравнивание байтов для структуры. Таким образом, у вас могут возникнуть проблемы с совместимостью, если ваш COM-сервер имеет другое выравнивание структуры с клиентом. например VB имеет 4-байтовое выравнивание, а #import в Visual C++ по умолчанию использует 8-байтовое выравнивание. Если у вас есть хоть малейший шанс в будущем использовать интерфейс в сценариях, избегайте использования структур.

Предлагаемое чтение:

person Sheng Jiang 蒋晟    schedule 06.05.2010
comment
Спасибо за быстрый ответ, я читаю ваши предложения. Один быстрый вопрос: я еще немного поиграл и смог придумать следующее: интерфейс ISimpleCom : IDispatch{ [id(1), helpstring(method Test2)] HRESULT Test2([in,out] SAFEARRAY(struct MyStruct) param) ; }; где MyStruct: struct MyStruct { long nLongValue; BSTR bstrStringValue; } ; Это отлично работало с С#. Это не должно было быть основано на ваших предложениях и прочитанном (или совместимо ли с автоматизацией SAFEARRAY?). C#: SafeArrayPlayLib.MyStruct[] myArray = new MyStruct[2]; com.Test2 (мой массив); С уважением, Дэйв - person Dave; 07.05.2010
comment
Спасибо Шэн. Я не буду использовать этот COM-компонент со скриптом, только C#. Спасибо за помощь. В наши дни трудно получить помощь по COM; это старая технология. - person Dave; 08.05.2010