Delphi COM object private attributes not accessible in multithreading


I’ve moved the following from the stackoverflow.com before I delete the post.  It was suggested that “It’s not a valid question if the answer can be found only using information that is not in the question. Also, SO is not a place where we debug your programs.”

I have a COM object,

TRadioTracer = class(TAutoObject, IRadioTracer)
private
   progress: integer;  // store 0 to 100

protected
   function GetProgress: integer;
   procedure DoWork;  // do some long work

procedure DoWork;
begin
  progress := 10;
  // do some long work here
end;

The GetProgress and DoWork are exported functions that are visible.

var
  obj: IRadioTracer;
  sc: IScriptControl;
begin
  sc := CreateOleObject("ScriptControl") as IScriptControl;
  obj := CreateOleObject("RadioTracer") as IRadioTracer;
  sc.AddObject("Worker", obj, true); // add to script control      
  Timer1.Enabled := True;   // start timer
  sc.ExecuteStatement("Worker.DoWork");
end;

I have also defined obj (above) as global variable. I enable the timer (Timer1) which updates a label with obj.GetProgress value before DoWork finishes. At the begining of DoWork, the value of progress is updated to 10. But the value never updates to the Timer1 as obj.GetProgress always return 0.

The weird thing is if I change ‘progress‘ variable to the global variable that is placed after implementation section, the value will be updated and returned in the Timer1.

The above is just a short illustration. I have also put the sc.ExecuteStatement in another thread (not the main thread).

Global Variables

It was actually not problem of my code, but the dynamic script code I put into the ExecuteStatement.

The problem is that in the script, I create a new object with the same name as “Worker” (in the example), so in fact, it will actually have two different objects (so they have different copy of private attribute progress). However the progress address is shared if put in the global scope after implementation.

In short, I did the following, and it works.

sc.AddObject("Worker", obj, true);

// The following will in fact create another new object, so there are two different of objects.
sc.ExecuteStatement("Dim Worker" + #13#10 + "Set Worker=CreateObject("RadioTracer")");

–EOF (The Ultimate Computing & Technology Blog) —

GD Star Rating
loading...
454 words
Last Post: Matrix Print in Batch for Fun
Next Post: Visual Studio .NET 4.0 Disables COM DLL protected by VMProtect

The Permanent URL is: Delphi COM object private attributes not accessible in multithreading

Leave a Reply