7

Here is a simple code:

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

Do we need to use the V := Unassigned code at the end, or will V is free when it exists the scope of Test procedure? in VB you set the variable to Nothing. do we need to do the same here? ie:

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;
kobik
  • 21,001
  • 4
  • 61
  • 121

1 Answers1

9

OleVariant will release the interface automatically when it goes out of scope. You can assign a new value to the OleVariant if you need it to be released sooner.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • How can that be verified? what happens when the `OleVariant` is assigned to `Unassigned` or `Null`? – kobik Nov 30 '11 at 08:59
  • 2
    Compile with debug 'dcu's, and put a breakpoint on [_VarClear](http://docwiki.embarcadero.com/VCL/en/System.VarClear) procedure in variants.pas – Sertac Akyuz Nov 30 '11 at 12:00
  • 1
    Assigning any value to an `OleVariant` (or a `Variant`, for that matter) will automatically free whatever data the `OleVariant` is currently holding on to, before then assigning the new value. That includes deallocating dynamic strings/arrays, releasing interface pointers, etc. – Remy Lebeau Nov 30 '11 at 21:50
  • using `V := Unassigned` will call `VariantClear` (oleaut32.dll), otherwise (doing nothing and getting out of scope) will trigger `_IntfClear`. I wonder why is that... and what is the best coding practice. – kobik Dec 04 '11 at 09:52
  • 4
    The compiler does not call `_IntfClear()` on an `OleVariant`. An `OleVariant` is a wrapper around an OLE `VARIANT` record, and thus has to be managed using OLE support functions (`VariantInit()`, `VariantClear()`, etc) only. When an `OleVariant` goes out of scope, the compiler should be calling `VariantClear()`. `_IntfClear()` is meant for releasing Delphi-style interface variables instead, which `OleVariant` is not. – Remy Lebeau Dec 05 '11 at 03:50
  • 4
    As for coding practice, you should let the `OleVariant` just go out of scope unless you need to reuse the variable, or have good reason to release/reclaim the `OleVariant`'s memory manually. – Remy Lebeau Dec 05 '11 at 03:52
  • @RemyLebeau, by "unless you need to reuse the variable" do you mean for example, if I want to reuse the same variable to point **another** OLE Object, I must first call `V := Unassigned', right? I'm currently fixing a "The RPC server is unavailable", and [another question(vb.net calling Word)](https://stackoverflow.com/questions/56999071/the-rpc-server-is-unavailable-when-looping-through-word-documents/57007091) said the samething as I understand it, but not quite sure if it also applies to calling Word from Delphi. – Edwin Yip Aug 20 '19 at 08:45
  • @EdwinYip depends. If you simply assign a new interface/array pointer, a previous one will be released automatically. But if you pass the variable to an external function that then assigns a new interface/array, you may have to explicitly clear the variable first. – Remy Lebeau Aug 20 '19 at 14:20