从托管代码通过COM调用包装COM可见的管理组件 [英] Calling COM visible managed component from managed code through COM wrapper

查看:139
本文介绍了从托管代码通过COM调用包装COM可见的管理组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个第三方组件,可以说FIPreviewHandler处理预览,它实现IPreviewHandler。 FIPreviewHandler被实现为一个被管理单元,并且使用通过互操作的装置的IPreviewHandler接口和相关接口。 FIPreviewHandler使用regasm.exe作为COM注册。

I have a 3rd party component, lets say FIPreviewHandler to handle preview, which implements IPreviewHandler. FIPreviewHandler is implemented as a Managed Component, and uses the IPreviewHandler interface and related interfaces through means of an interop. FIPreviewHandler is registered using regasm.exe as COM.

我有一个客户端应用程序也被托管。我想创建FIPreviewHandler的实例作为我的应用程序一个COM组件。

I have a client application which is also Managed. I want to create an instance of FIPreviewHandler as a COM component in my application.

我有一个定义IPreviewHandler及相关接口的互操作程序集。

I have an interop assembly that defines IPreviewHandler and related interfaces.

当我创建FIPreviewHandler的一个实例,使用Activator.CreateInstance(),由GetTypeByCLSID(),它使用了正确的CLSID为FIPreviewHandler返回一个类型,它返回我一个管理的实例,因为它提供的实际装配,并跳过COM。当我尝试QI /施放此实例作为任何界面,IPreviewHandler例如,因为,它加载为管理对象返回null,虽然由FIPreviewHandler实现的IPreviewHandler接口是相同的接口,因为我有我的互操作的,但其在差命名空间/组装,因此空。如果是回到了我一个COM实例/ RCW(系统.__ ComObject),它不会采取空间考虑,并会投罚款,并返回一个有效的实例。

When I create an instance of FIPreviewHandler, using Activator.CreateInstance(), on a type returned by GetTypeByCLSID(), which uses the correct CLSID for FIPreviewHandler, it returns me a managed instance, as it has the actual assembly available, and skips COM. When I try to QI/cast this instance as any of the interfaces, IPreviewHandler for example, it returns null because, it is loaded as a managed object, and although the IPreviewHandler interface implemented by FIPreviewHandler is the same interface as I have in my interop, but its in a difference namespace/assembly, hence null. If it were to return me a COM instance/RCW (System.__ComObject), it would not take namespace into account, and would cast fine, and return a valid instance.

FIPreviewHandler是一个32位组件,64位Win7的机器上,如果我编译我的客户端应用程序为任何CPU,Activator.CreateInstance()返回一个COM实例/ RCW(系统.__ ComObject),因为它cudnt找到64位实施FIPreviewHandler的,因此返回的代理。在这种情况下,我的应用程序工作正常。但是,当我编译它在x86,它得到了32位执行,并返回实际管理类的管理的实例,而不是一个COM实例,因此失败。

FIPreviewHandler is a 32 bit component, and on a 64bit Win7 machine, if I compile my client application as "Any CPU", Activator.CreateInstance() returns a COM instance/RCW (System.__ComObject), as it cudnt find a 64bit implementation of FIPreviewHandler, hence returns a proxy. In this scenario, my application works fine. But when I compile it for x86, it gets the 32bit implementation, and returns a managed instance of the actual managed class, and not a COM instance, hence fails.

我不能使用FIPreviewHandler的程序集中定义的接口,因为我不得不写IPreviewHandler一个通用的客户端,我的应用程序将实现IPreviewHandler任何成分,它会工作非常适合基于C ++的客户端访问FIPreviewHandler作为一个COM对象工作,但失败了管理的客户端。

I cannot use the interfaces defined in FIPreviewHandler's assembly, as I have to write a generic client for IPreviewHandler, and my application will work with any component implementing IPreviewHandler, which would work great for C++ based clients accessing FIPreviewHandler as a COM object, but is failing for Managed clients.

我希望我有道理,我会任何帮助真的很感激。

I hope I make sense and I would be really grateful for any help.

推荐答案

我试图做类似的事情,但没有成功。 (在我的情况下,现有的定义COM接口有这意味着它不能在.net中实现一个bug,所以在不同的命名空间我重新定义了COM接口自己和实现了这个接口,而不是所得到的对象实现了正确的COM 。接口,但我不能让一个COM包装投回到原来的破接口)的持有

I've tried to do a similar thing with no success. (In my case the existing defined COM interface had a bug that meant it couldn't be implemented in .Net, so I re-defined the COM interface in a separate namespace myself and implemented this interface instead. The resulting object implemented the correct COM interfaces, however I couldn't get a hold of a COM wrapper to cast back to original broken interface).

据我所知,目前只有2解决方案:

As far as I am aware there are only 2 solutions:


  1. 声明中的主Interop大会,(使用的,以便所有接口都在一个共同的命名空间中定义TLBIMP 或手动)。请注意,这通常装配不包含任何实现,因此不应该需要参考其他组件(除非其他组件是的那些声明依赖COM接口互操作程序集)。

  1. Declare all COM interfaces in a Primary Interop Assembly, (either using TLBimp or by hand) so that all interfaces are defined in a common namespace. Note that this assembly normally doesn't contain any implementation, and so shouldn't need to reference other assemblies (unless those other assemblies are also interop assemblies that declare dependent COM interfaces).

创建一个包装(例如,在托管C ++)执行通过传统的COM,而不是通过.NET COM互操作。

Create a wrapper (for example in Managed C++) that performs the calls through "traditional" COM, rather than through the .Net COM interop.

选项1.绝对令我最好的选择 - 注意,无需注册该组件或将其放置在GAC和实施可以在一个完全独立的组件,只要共同互操作程序集被引用。

Option 1. definitely strikes me as your best option - note that there is no need to register this assembly or place it in the GAC, and the implementation can be in an entirely separate assembly as long as the common interop assembly is referenced.

我想不出有很多合法的情况下主Interop大会是不可行的。

I can't think of many legitimate situations where a Primary Interop Assembly is not feasible.

这篇关于从托管代码通过COM调用包装COM可见的管理组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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