2013-08-21 10 views
5

私はしばらくの間プログラミングしてきましたが、COM/ActiveXオブジェクトに関しては、私の知識が明らかに上回っている非常に奇妙な問題に直面しています。 ここにあります。 私のソフトウェアは、レイトバインディングを使用してCOMオブジェクトと通信します。 これらのCOMオブジェクトはハードウェア(例えば、科学的なカメラなど)と話すので、私はすべての呼び出しを専用のスレッドにするように選択しました。これにより、メインスレッドはユーザーと対話できます。 メインのユーザスレッド(または他のスレッド)から、activeXだけを扱うように設計されたスレッドにメッセージを送ります。それがどのように見えるかここでDelphi COMオブジェクトマルチスレッド


 

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; 

これは、ほとんどのCOMサーバと魔法のように動作しますが、私はプロセスに気づいた特に、Visual Basicで書かれた他のCOM DLL /サーバー、で失敗私が上記のことをしていたにもかかわらず、ActiveXコードがメインスレッドに実行されることを確認します。 結果結果 で - メインスレッド を保持 - (例えば、大きな配列を持つ)、メインスレッドのメモリ破損... ==私のアプリがクラッシュ

原因は何ですか?これはActiveXスレッディングモデルに関連していますか? これに対処するためのコードを理解して修正したいと思います(その場合、COMはメインスレッドで実行されます)。

ありがとう 理解するために、より多くの情報を提供する準備ができて)

+0

*上記のことにもかかわらず、ActiveXコードがメインスレッドに実行されることがプロセスエクスプローラに気づいています。 COM *サーバ*コードがアプリのメイン*クライアント*スレッド上で実行されることをどうやって知っていますか? [GetCurrentThreadId](http:// msdn)を表示する[OutputDebugString](http://msdn.microsoft.com/en-us/library/windows/apps/aa363362(v = vs.85).aspx)を追加することをお勧めします。可能であれば、microsoft.com/en-us/library/windows/apps/ms683183(v=vs.85).aspx)。デバッグ出力に[DebugView](http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx)を使用できます。 – avo

+0

私はprocessexplorerを使用していますが、これは非常に効果的なツールです。 –

答えて

0

COMオブジェクトがメイントレッドにディスパッチされたため、CoInitializeEx(nil、COINIT_MULTITHREADED)を使用するとCoInitializeよりも優れています。

0

CreateOLEObjectが内部CoCreateInstanceを使用し、そしてのみCLSCTX_LOCAL_SERVER(SOなしCLSCTX_INPROC_SERVER)としてdwClsContextを通過させることによって、特定のDllhost.exeに任意のDLLをロードするためにCOMを強制すべきです。私は自分で試してみるためにここに道具を持っていませんが、余分なラッピングをすることでこれがあなたの問題を解決するかもしれません。

this questionも参照してください。

+0

ここに私は、答えの一部があると思います: http://stackoverflow.com/questions/12487282/com-object-methods-are-not-executed-on-the-thread-that-c​​oinitialize-d-and作成する –

関連する問題