Как правильно управлять памятью при использовании COM-объектов в VB? - PullRequest
4 голосов
/ 28 февраля 2010

Может кто-нибудь объяснить, как происходит распределение / перераспределение памяти при передаче значений между COM-объектом и VB.

Мои проблемы: 1.

IMyInterface::Method1 ([in] BSTR* pVal, [in] SAFEARRAY(BSTR)* pArray);

нам нужно освободить выделенную память для вышеуказанных параметров внутри COM-объекта?

2.

IMyInterface::Method2 ([in, out] BSTR* pVal);

В этом случае VB позаботится об освобождении памяти для возвращаемых значений COM? (COM-объект выделяет память для этих возвращаемых значений)

3

IProxy_MyInterface::Event1 ([in] BSTR* pVal);

Как только событие будет обработано внутри VB, снова будет ли выделяться выделение памяти для параметров VB?

Ценю вашу помощь.

Спасибо

Ответы [ 3 ]

2 голосов
/ 22 февраля 2011

Чтение официальных документов (Allocating and Releasing Memory for a BSTR):

http://msdn.microsoft.com/en-us/library/xda6xzx7.aspx

Вот описание всех ваших дел.

1 голос
/ 28 февраля 2010

[in] параметры должны быть выделены вызывающей стороной и освобождены вызывающей стороной, если в документации API не указано иное.

Параметр [in, out] менее понятен, так как это BSTR *, возможно, что BSTR, который вы передаете, будет освобожден и возвращен другой BSTR, поэтому вы должны освободить BSTR, который возвращается, а не тот, который вы прошло.

[out] и [out, retVal] означают передачу права владения памятью, функция выделяет память, и вызывающий затем отвечает за освобождение памяти.

Для BSTR в C / C ++ COM вы должны использовать SysAllocString и SysFreeString для выделения и освобождения.

0 голосов
/ 28 февраля 2010

VB6 имеет три случая объявления строковых параметров - ByVal param As String, ByRef param As String и Function() As String. Первый в IDL соответствует [in] BSTR param, второй - [in, out] BSTR *param, третий - [out, retval] BSTR *retval.

Нет никакого способа, которым VB6 может объявлять параметры [in] BSTR * или [out] BSTR *, но он все еще может использовать их, то есть он может вызывать методы (в VC), класс которых имеет параметры, объявленные как out-only, или любой другой поддерживаемый IDL способ .

Также обратите внимание, что BSTR сам по себе является указателем typedef, что-то вроде wchar_t *, поэтому BSTR * на самом деле wchar **. IDL нужен указатель для наших параметров, поэтому вы не можете объявить [out] int param, а [out] BSTR param также странно.

Как только [in] BSTR * путаница становится ясной (это ненужная странная двойная косвенность, необходимая для out-параметров, но не только для ввода), простое правило состоит в том, что, когда у вас есть * в объявлении param, вызывающий должен освободить его после вызов метода, если он уже не равен NULL.

[in, out] SAFEARRAY(BSTR)* pArray отображается на ByRef pArray() As String в VB6, и вы не можете изменить это значение на ByVal, т. Е. * Требуется для VB6, поэтому он не может быть только-только, и вызывающая сторона должна освободить безопасный массив. Это не единственный безопасный массив.

...