我已经编程了一段时间,关于COM / ActiveX对象,我面临着非常奇怪的问题,这些问题显然超出了我的知识 . 这里是 . 我的软件使用后期绑定与COM对象进行通信 . 由于这些COM对象与硬件(例如科学相机)通信,我选择将所有调用都切换为专用线程 . 这允许主线程与用户交互 . 所以我将消息从主用户线程(或任何其他线程)发送到专门处理activeX的线程 .
这是它的样子
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服务器的魅力一样,但是与其他COM DLL / Server失败了,特别是用visual basic编写,我注意到了进程浏览器,尽管我在上面做了什么,但是ActiveX代码被执行到主线程中!结果导致 - 主线程阻塞 - 主线程内存损坏(例如,使用大型数组)... ==我的应用程序崩溃
原因是什么?这与ActiveX线程模型有关吗?我想了解并纠正我的代码以应对(在这种情况下,COM将在主线程中运行....)
谢谢(因为我花时间在这上面,我准备提供更多信息以便了解)
2 回答
使用CoInitializeEx(nil,COINIT_MULTITHREADED)优于CoInitialize ...因为COM对象被分派到主踏板中 .
CreateOLEObject
在内部使用CoCreateInstance,并且仅将dwClsContext
作为CLSCTX_LOCAL_SERVER
传递(因此没有CLSCTX_INPROC_SERVER
),应强制COM将任何DLL加载到特定的dllhost.exe中 . 我没有在这里尝试自己的工具,但通过额外的包装,这可以解决您的问题 .另见this question .