Освобождаване на 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 задавате променливата на нищо. трябва ли да направим същото тук? т.е.:

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