The compiler explicitly uses the implicit local interface variable for the return value from CreateOleObject . Then it is released at the end of the procedure, too late for you.
There are several ways to defeat this. First of all, you can explicitly specify a reference to the IDispatch interface returned by CreateOleObject . This allows you to control your life time.
procedure Test; var intf: IDispatch; LLibrary: OleVariant; begin CoInitialize(nil); try intf := CreateOleObject(LibraryName); try LLibrary := intf; finally VarClear(LLibrary); intf := nil; end; finally CoUninitialize; end; end;
An alternative would be to move the code that called CreateOleObject to a separate routine with its own scope.
procedure DoWork; var LLibrary: OleVariant; begin LLibrary := CreateOleObject(LibraryName); //do stuff with LLibrary end; procedure Test; begin CoInitialize(nil); try DoWork; finally CoUninitialize; end; end;
Since the implicit local link is within DoWork , it is freed at the end of DoWork and therefore before running CoUninitialize .
My recommendation is to use the second option, which is cleaner and forces the compiler to do the work on your behalf.
David heffernan
source share