Могу ли я отправить список объектов через COM? У меня есть свой класс, а также есть список этого класса. И мне нужно отправить это через функцию COM. Могу ли я сделать это? Если да, то как? Нужен ли маршалинг сериализации?
Как отправить список через COM
Ответы (3)
COM не фиксирует какой-либо конкретный тип коллекции, и уж точно не имеет ничего стандартного, моделирующего список. По соглашению вы можете моделировать любую коллекцию с помощью интерфейса. Допустим, у вас есть коллекция объектов Foo, каждый из которых реализует IFoo. Затем объявите интерфейс IEnumFoo, аналогичный следующему:
interface IEnumFoo : IUnknown
{
HRESULT Next( [in] ULONG celt,
[out, size_is(celt), length_is(*pceltFetched)] IFoo **rgelt,
[in,out,unique] ULONG *pceltFetched );
HRESULT Skip( [in] ULONG celt);
HRESULT Reset();
HRESULT Clone( [out] IEnumFoo **ppenum );
}
А затем просто верните указатель интерфейса на реализацию этого интерфейса, чтобы позволить клиентскому коду перечислить список. Ознакомьтесь с документами MSDN для IEnumVARIANT, очень распространенного типа интерфейса перечисления для вариантов. Что также объясняет, что делают методы.
Если одна сторона интерфейса будет написана на языке с "более простой" системой типов, такой как VB6 или сценарий, то SAFEARRAY - это то, что вам нужно. Об этом может позаботиться универсальный маршаллер COM.
Если у вас есть C++ на обеих сторонах интерфейса, и вы готовы определить интерфейс в IDL и сгенерировать пользовательский код сортировки, тогда IDL включает атрибут size_is, который можно использовать. См. здесь Детали.
В любой разумной степени это невозможно сделать с помощью std::list. Я уверен, что есть какой-то маньяк, который мог бы справиться с этим, но по моему опыту, оно того не стоит. Если это не обязательно должен быть std::list и просто какой-то связанный список, вам придется либо определить новый COM-интерфейс и предоставить его реализацию (которая может быть просто оболочкой вокруг std::list), либо найти какой-нибудь сторонний ресурс, имеющий адекватную реализацию для ваших целей. Если у вас нет большого опыта в реализации COM-интерфейсов, вам нужно хорошенько прочитать.
Если это может быть массив, то вы можете сделать свою жизнь намного проще, используя SAFEARRAY. А SAFEARRAY проще использовать с CComSafeArray< ATL. /a>, который в значительной степени является оболочкой. Он пытается помочь/избавить вас от таких проблем, как подсчет ссылок, при работе с COM-объектами. Затем вы можете просто передать массив между вашими COM-объектами. Сразу напомню, что нужно еще обратить внимание на то, кто отвечает за де-аллокацию памяти.