Как передать массив структур (содержащих std:string или BSTR) из ATL в C#. SafeArray? Вариант?
У меня есть ATL COM-объект, который я использую из C#. Интерфейс в настоящее время выглядит так:
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 creationDate; идентификатор строки; резюме строки; }; Все члены структуры являются std:: string. У меня есть массив из них, что мне нужно, чтобы вернуться к C#. Какой лучший способ сделать это?
Я подозреваю, что кто-то скажет: "эй, вы не можете просто отправить std:: string через COM таким образом. Если это так, хорошо, но каков наилучший способ изменить структуру? Измените std:: string на BSTR? И затем, как мне: 1) настроить IDL для передачи массива структур (структур с BSTR или std::string) 2) если я должен использовать SAFEARRAYS, как мне заполнить SAFEARRAYS структурами.
Я не знаком с COM, за исключением использования с простыми типами.
1 ответ
Определяемая пользователем структура несовместима с интерфейсом автоматизации. Вероятно, вы можете создать вложенный массив или двумерный безопасный массив BSTR, но более приемлемым решением было бы обернуть структуру как объект автоматизации с 3 свойствами, а затем обернуть массив как коллекцию, имеющую перечислитель.
Ни IDL, ни Automation не определяют выравнивание байтов для структуры. Таким образом, у вас могут возникнуть проблемы с совместимостью, если ваш COM-сервер имеет другое выравнивание структуры с клиентом. например, VB имеет 4-байтовое выравнивание, в то время как #import в Visual C++ по умолчанию имеет 8-байтовое выравнивание. Если в будущем у вас есть малейший шанс использовать интерфейс в сценариях, избегайте использования структур.
Предлагаемое чтение:
- " Передача структур через IDispatch" от Don Box, Microsoft Systems Journal, июнь 1996 г.
- * Принципы разработки интерфейсов коллекции и перечислителя
- * Внутренние компоненты ATL: работа с ATL 8 Крис Таварес, Кирк Фертитта, страница 392