6

I've been programming for a while and regarding COM/ActiveX object, I'm facing very strange issues, that are abviously above my knowledge. Here it is. My software talks to COM objects using late binding. Since those COM object talk to hardware (such as scientific camera for instance), I have choosen to seralise all calls into a dedicated thread. this allows the main thread to interact with the user. So I'm sending messages from the main user thread (or any other thread) to the thread that is design to dealing solely with activeX.

Here how it looks


procedure MythreadActiveX.execute;
begin

  CoInitialize(nil);
  Try

  ComObject       :=CreateOLEObject(COMID);

  While not Terminated do
  Begin

  If PeekMessage(Msg,0,0,0,PM_REMOVE) then 
    Begin
     TranslateMessage(Msg); 
     DispatchMessage (Msg); 
    end;

    If (FEvent.WaitFor(TimOutMs)=wrSignaled) then   // Wait for command
    Begin

      FEvent.ResetEvent;

      Try

      Case COM_Order of
          Oder1:Begin
                 .........
                end    
          Oder2:Begin
                 .........
                end    
      end;

      FEventComplete.SetEvent;

    end;
   end; 

   CoUnInitialize;
end;

This works like a charm with most COM server, but fails with other COM DLL/Server, especially written in visual basic, where the I have noticed with process explorer that the ActiveX code is executed into the main thread despite what I did above ! The consequence result in - main thread holding up - main thread memory corruption (with large array for instance)... == my app crash

What is the cause ? is this related to ActiveX threading model ? I would like to understand and to correct my code to cope with that (In that case, the COM shall run in the main thread....)

Thanks (Since I spent time on this, i'm ready to provide more information in order to understand)

4

2 回答 2

1

Using CoInitializeEx(nil,COINIT_MULTITHREADED) is better than CoInitialize...because the COM object was dispatched into the main tread.

于 2013-08-24T01:58:17.387 回答
0

CreateOLEObject uses CoCreateInstance internally, and by passing dwClsContext as CLSCTX_LOCAL_SERVER only (so no CLSCTX_INPROC_SERVER), should force COM to load any DLL into a specific dllhost.exe. I don't have the tools here to try for myself, but with the extra wrapping this might solve your problem.

See also this question.

于 2013-08-21T06:47:11.357 回答