Как вернуть из ActiveX-компонента структуру или массив?

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
Ivan093
Сообщения: 54
Зарегистрирован: 28 июн 2007, 13:59
Откуда: Екатеринбург
Контактная информация:

06 июл 2007, 15:13

Romeo писал(а):Кстати, Ivan093, Obj - это как раз и есть сам COM объект. Никакая это не обёртка. Тэмплэйт параметр является бызовым классом. Такой подход называется виртуальным наследованием и повсеместно использутся в ATL.
Елка-Палки, запутался я что-то... :)
Дак все-таки надо или нет удалять Obj и в каком месте?
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

06 июл 2007, 15:14

Romeo писал(а):Ты со мной споришь, или с концепцией COM? Это не я придумал, Absurd :)
Где-то я читал что когда кому-то вовне передаешь интерфейс надо сделать AddRef, а когда получил интерфейс извне - надо сделать Release(). Объясняется гетерогенной тредовой архитектурой COM. Возможно, это было давно и неправда. Но йаъ СОМ код не пишу, расслабтесь.
Romeo писал(а): Ну так это кривой программный код. И не поможет в это случае ни классический подход передачи параметров, ни тот, который изобрёл и пытаешься отстаивать ты :)
Удалять надо там, где и создал, согласен.
2B OR NOT(2B) = FF
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

06 июл 2007, 15:16

Romeo писал(а):Кстати, Ivan093, Obj - это как раз и есть сам COM объект. Никакая это не обёртка. Тэмплэйт параметр является бызовым классом. Такой подход называется виртуальным наследованием и повсеместно использутся в ATL.
То есть там перегружен operator new, и как следствие объект создается не в С++ куче?
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

06 июл 2007, 15:21

Ещё одно замечане. Создавать COM объекты на уровне C++ принятно вот так:

Код: Выделить всё

CComObject<TInterface2>* pObj = NULL;
CComObject<TInterface2>::CreateInstance(&pObj);
Это почти тоже самое, что и new, но в случае CreateInstance происходит вызов некоторых инициализирующих методов COM объекта уровня C++, таких, как FinalConstruct. Если ты не используешь перегрузку FinalConstruct, то для тебя сойдёт и new. Но здесь, сам понимаешь, речь идёт не о том как будет работать, а о том, как правильно. Так вот правильно - это использовать CreateInstance.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

06 июл 2007, 15:28

&quot писал(а):То есть там перегружен operator new, и как следствие объект создается не в С++ куче?
Не понял о чём ты. Я всего лишь о том, что есть если есть определение.

Код: Выделить всё

class A
{
...
};

class B: public A
{
...
};
То в этом случае говорят, что класс В в том числе является и классом A (отношение "is"). Когда же говорят об обёртке то имеется в виду определение:

Код: Выделить всё

class A
{
...
};

class B
{
...
A a;
};
Это отношение называется "has".

Так вот CComObject<T> является (is) T, а не оборачивает (has) T по той причине, что наследуется от тэмплэйт параметра, как я уже заметил ранее.

(С) Основы С++.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

06 июл 2007, 15:30

Ivan093, не обращай внимание на нашу с Абсурдом перепалку. Мы здесь этим частенько занимаемся :) Главное, что тебе помогли в процессе обсужения :)
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

06 июл 2007, 15:38

&quot писал(а):Елка-Палки, запутался я что-то...
Дак все-таки надо или нет удалять Obj и в каком месте?
Нет, не надо. Его удалит VB Script, когда переменая-объект выйдёт из области видимости.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

06 июл 2007, 16:12

Romeo писал(а):Это отношение называется "has".

Так вот CComObject<T> является (is) T, а не оборачивает (has) T по той причине, что наследуется от тэмплэйт параметра, как я уже заметил ранее.
Йаъ понял. Release() при счетчике ссылок = 1 приводит к delete this;
2B OR NOT(2B) = FF
Аватара пользователя
Romeo
Сообщения: 3091
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

06 июл 2007, 16:15

&quot писал(а):Йаъ понял. Release() при счетчике ссылок = 1 приводит к delete this;
Ура, Absurdище, добро пожаловать в COM! :D
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

06 июл 2007, 22:18

Romeo писал(а):Ситуации, когда Вызывающий делает AddRef, а Получающий делает соответствующий Release быть не должно. Это грубое нарушение концепции COM.
Перечитал Windows 2000 Systems Programming Black Book. Там все же написано что если интерфейс передается в другой поток, на него надо сделать AddRef, а в получающем потоке - Release. Кроме того, методы возвращающие интерфейс (IXMLDOMElement->get_childNodes(...)) подразумевают что клиент этот интерфейс освободит сам. То есть разбалансировка кто создает <-> кто удаляет присутствует в COM повсеместно.
2B OR NOT(2B) = FF
Ответить