Освобождение OleVariant после использования CreateOleObject

Вот простой код:

procedure Test;
var
  V: OleVariant;
begin
  V := CreateOleObject('ADOX.Catalog');
  try
    // do something with V...
  finally
    V := Unassigned; // do we need this?
  end;
end;

Нужно ли нам использовать код V := Unassigned в конце, или V будет бесплатным, когда он существует в рамках процедуры Test? в VB вы устанавливаете переменную в Nothing. нам нужно сделать то же самое здесь? то есть:

function VarNothing: IDispatch;
// emulate VB function SET VarX = Nothing
var
  Retvar: IDispatch;
begin
  Retvar := nil;
  Result := Retvar;
end;

// do something with V and finally:
V := VarNothing;

person kobik    schedule 29.11.2011    source источник


Ответы (1)


OleVariant автоматически освобождает интерфейс, когда он выходит за рамки. Вы можете присвоить новое значение OleVariant, если вам нужно, чтобы оно было выпущено раньше.

person Remy Lebeau    schedule 29.11.2011
comment
Как это можно проверить? что происходит, когда OleVariant назначается Unassigned или Null? - person kobik; 30.11.2011
comment
Скомпилируйте с помощью debug 'dcu's и установите точку останова на процедуре _VarClear в вариантах. па - person Sertac Akyuz; 30.11.2011
comment
Присвоение любого значения OleVariant (или Variant, если уж на то пошло) автоматически освобождает любые данные, которые в настоящее время удерживает OleVariant, прежде чем присваивать новое значение. Это включает освобождение динамических строк/массивов, освобождение указателей интерфейса и т.д. - person Remy Lebeau; 01.12.2011
comment
использование V := Unassigned вызовет VariantClear (oleaut32.dll), в противном случае (ничего не делая и выходя за рамки) вызовет _IntfClear. Интересно, почему это так... и какова наилучшая практика кодирования. - person kobik; 04.12.2011
comment
Компилятор не вызывает _IntfClear() для OleVariant. OleVariant — это обертка записи OLE VARIANT, поэтому ею нужно управлять только с помощью функций поддержки OLE (VariantInit(), VariantClear() и т. д.). Когда OleVariant выходит за рамки, компилятор должен вызывать VariantClear(). _IntfClear() предназначен для освобождения переменных интерфейса в стиле Delphi, а OleVariant — нет. - person Remy Lebeau; 05.12.2011
comment
Что касается практики кодирования, вы должны позволить OleVariant просто выйти из области видимости, если вам не нужно повторно использовать переменную или у вас есть веская причина для освобождения/восстановления памяти OleVariant вручную. - person Remy Lebeau; 05.12.2011
comment
@RemyLebeau, если вам не нужно повторно использовать переменную, вы имеете в виду, например, если я хочу повторно использовать одну и ту же переменную для указания другого объекта OLE, я должен сначала вызвать `V := Unassigned', правильно ? В настоящее время я исправляю сервер RPC недоступен и другой вопрос (vb.net, вызывающий Word) сказал то же самое, насколько я понимаю, но не совсем уверен, применимо ли это также к вызову Word из Delphi. - person Edwin Yip; 20.08.2019
comment
@EdwinYip зависит. Если вы просто назначите новый указатель интерфейса/массива, предыдущий будет освобожден автоматически. Но если вы передаете переменную внешней функции, которая затем назначает новый интерфейс/массив, вам, возможно, придется сначала явно очистить переменную. - person Remy Lebeau; 20.08.2019