COM在多线程中的接口共享

场景大概是这样的:

建一个工程,添加个窗体,上面放个TmpWeb:TWebBrowser,然后访问一个站点,再获取页面中的一个button元素,并点击它。

通常情况下这样写没有什么问题:

var
  o:OleVariant;
begin
    o := TmpWeb.oleobject.document.all.item('go',0);
    o.click;
end;

因为所有的东西,都是一个主线程内。

但如果我们在多线程中使用,就有问题了,会报av错误,在这一段:

  o := TmpWeb.oleobject.document.all.item('go',0)

原因就在于COM的对象都生活在套间里,拥有线程相关性。如果我们只访问TmpWeb.Tag或者TmpWeb.Height这类自有属性,那自然不会有问题,但如果A线程要共享一个COM接口,比如说是IHTMLDocument,则不可以直接就把指针copy或者共享给B线程,此时需要向系统注册一个cookie,DWORD格式,然后B线程把这个cookie还原成接口指针。

具体操作如下:

1.创建一个全局变量,如:

var
  MarshalStream:pointer;

 

2.A线程将IHTMLDocument注册成cookie

var
  WebDoc:IHTMLDocument2;
begin
    WebDoc:=TmpWeb.Document as IHTMLDocument2;
    CoMarshalInterThreadInterfaceInStream(IID_IHTMLDocument2, WebDoc, IStream(MarshalStream));
end;

3.B线程将cookie还原成指针

var
  WebDoc:IHTMLDocument2;
  o:OleVariant;
begin
    CoGetInterfaceAndReleaseStream(IStream(MarshalStream),IID_IHTMLDocument2,WebDoc);
    o := WebDoc.all.item('go',0);
    o.click;
end;

通过这样的方式,就可以在不同的线程中,共享COM接口了。

另外,在线程中使用COM时,不要忘了最基础的CoInitialize(nil)和CoUnInitialize。

 

转载于:https://www.cnblogs.com/rockmmm/p/6904329.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值