从多线程单元中使用线程模型单元访问COM dll时出错 [英] Error when accessing a COM dll with Threading Model Apartment from Multithread Apartment

查看:91
本文介绍了从多线程单元中使用线程模型单元访问COM dll时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须与第三方应用程序进行通信,唯一的方法是访问提供的COM组件.由于互动大约需要3分钟,因此必须在后台进行. 因此,我试图做的是添加一个带有选项"embedd interop-types" = true的组件的引用,并创建一个通过接口读取非常基础的数据的测试.记录此代码的方法是通过以下代码:

I have to communicate with a third party application and the only way to do so is by accessing the provided COM component. Because the interaction takes about 3 minutes it's mandatory that it takes place in the background. So what i tried to do is to add a reference the component with option "embedd interop-types" = true and to create a test that reads very basic data through the interface. The documented way to do so is by following Code:

System sys = new System();
if(Convert.ToBoolean(sys.Initialize()) && Convert.ToBoolean(sys.Login("John Smith", out userInstance)))
Project proj = new Project();
if (Convert.ToBoolean(proj.Open(sys, m_projName, m_scenarioName)))
    someValue = proj.Name;

这可以完美工作,直到使用BackgroundWorker.然后在第一行代码中出现以下错误:

this works perfectly until the BackgroundWorker is used. Then I get following error in the first line of code:

无法将类型为"System .__ ComObject"的COM对象转换为接口类型为"ICAPILib.System".该操作失败是因为在COM组件上对具有IID'{1F5EB3E2-35F6-11D2-A191-0060083A260B}'的接口的QueryInterface调用由于以下错误而失败:加载类型库/DLL出错. (来自HRESULT的异常:0x80029C4A(TYPE_E_CANTLOADLIBRARY).)

Unable to cast COM object of type 'System.__ComObject' to interface type 'ICAPILib.System'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{1F5EB3E2-35F6-11D2-A191-0060083A260B}' failed due to the following error: Error loading type library/DLL. (Exception from HRESULT: 0x80029C4A (TYPE_E_CANTLOADLIBRARY)).

我已经尝试过重新注册组件,但没有成功.

I already tried ReRegistering the Component without any success.

使用BackgroundWorker时,线程单元类型显然是MTA. COM组件的ThreadingModel设置为单元.如果我理解这篇文章 http://msdn.microsoft.com/en-us/library/eaw10et3.aspx 正确地,互操作性编组应注意访问对象.

When using the BackgroundWorker the Thread Apartment Type obviously is MTA. The COM component has ThreadingModel set to apartment. If I understood this article http://msdn.microsoft.com/en-us/library/eaw10et3.aspx correctly the interop marshalling should take care of accessing the Objects.

有人知道我可以尝试做些什么吗?

Does anybody have a clue what I could try to make this work?

推荐答案

发生的情况是COM Marshaller无法封送该对象.

What has happenned is that the COM Marshaller was unable to marshal the object.

第一个答案:标准编组需要类型库.可能是对象的类型库未正确注册,因此出现错误.您使用的是x86还是x64?尝试向REGTLB注册该库.

First answer: Standard marshalling requires a type library. It may be that the object's type library is not correctly registered, hence the error. Are you on x86 or x64? Try registering the library with REGTLB.

第二个答案::如果这不起作用,简单的答案是使用STA公寓类型的线程.这可能意味着您不能使用BackgroundWorker,但是可能必须使用专门创建的线程,该线程在完成时会销毁.如果我们谈论的是三分钟的操作,那么额外的开销可以忽略不计.

Second answer: If that doesn't work, the easy answer is to use a thread of STA apartment type. This may mean you cannot use a BackgroundWorker but may have to use a specially created thread which you destroy when completed. If we are talking about a three minute operation, the additional overhead is negligible.

请注意,必须在要使用该对象的线程上创建该对象,并且单元类型msut必须与该对象的线程模型兼容,以避免编组.

Note the object must be created on the thread from which it is to be used, and the apartment type msut be compatible with the object's threading model, to avoid marshalling.

这篇关于从多线程单元中使用线程模型单元访问COM dll时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆