.NET实施的C ++接口,暴露于COM [英] .NET implementation of C++ interface, exposing to COM

查看:169
本文介绍了.NET实施的C ++接口,暴露于COM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我敢肯定的回答我的问题是许多线程的组合已经present在这个论坛。也许你可以帮我把拼在一起。

I'm sure the answer to my issue is a combination of many threads already present on this forum. Maybe you can help me put the pieces together.

所以,我的问题是,我有一些C ++ code实现看起来像这样的接口:

So my challenge is, I have some C++ code that implements an interface that looks like this:

interface ItsSupplier : IDispatch {
    [propget, id(1), helpstring("property name") HRESULT Name([out, retval] BSTR* pVal);
}

实现此接口的DLL,是一个可用的插件的第三方软件。 我想使.NET编写一个插件。 由于使用的插件也不是.NET软件,我asume该DLL必须是COM对象。

The DLL which implements this interface, is a usable plugin in a third party software. I want to make a plugin written in .NET. Since the software using the plugins is not .NET, I asume that the DLL have to be a COM object.

下面是我如何去了解它在.NET。

Here is how I go about it in .NET.

[Guid("xxxx")]
public interface ItsSupplier {
    [DispId(1)]
    [return: MarshalAs(UnmanagedType.Bstr)]
    string Name { get; }
}

[Guid("xxxx"),
ClassInterface(ClassInterfaceType.AutoDispatch),
ComSourceInterfaces(typeof(ItsSupplier))]
    public class SupplierClass : ItsSupplier
    {
        public string { get { return "someName"; } }
    }
}

在项目设置,我已经检查注册为COM interorp。

Under project settings, I have checked "Register for COM interorp".

生成后,我跑regasm testDll.dll

After build I run "regasm testDll.dll"

我的问题是...

这是不是正确的方式来定义ItsSupplier界面自己?我的意思是,这是第三方软件需要一个接口,因此将它必须somwhere其他参考?

Is it the right way to define the ItsSupplier interface myself? I mean, this is a interface which the third party software expects, so will it have to be referenced somwhere else?

我这样做是正确的,当它涉及到了COM互操作的一部分?

Am I doing it right, when it comes to the COM interop part?

我希望我解释这个正确的:)

I hope I'm explaining this right :)

干杯 /托马斯

----------------编辑后的响应给Hans ------------------------

---------------- EDIT AFTER RESPONSE FROM HANS ------------------------

当我建立了TLB文件,并查看原始和我在OLEVIEW版本,这是我所得到的。

When i build the tlb file and view the original and my version in Oleview, this is what I get.

下面是原来的界面插件,看起来像在OLEVIEW:

Here is what the original interface plugin looks like in Oleview:

[
  odl,
  uuid(370B4079-40BB-47C9-B797-33B3B5422685),
  helpstring("ItsSupplier Interface"),
  dual,
  oleautomation
]
interface ItsSupplier : IDispatch {

下面是我的样子:

[
  odl,
  uuid(370B4079-40BB-47C9-B797-33B3B5422685),
  version(1.0),
  dual,
  oleautomation,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "COMDLL.ItsSupplier")    

]
interface COMDLL_ItsSupplier : IDispatch {

在COMDLL我的Visual Studio项目的名称。你认为问题?

The "COMDLL" Is the name of my visual studio project. Do you think that matters?

/托马斯

推荐答案

没有,很多细微的失误,将让你陷入困境。首先,在C ++接口声明了一个双接口,同时支持早期绑定,并通过IDispatch后期绑定。你必须使用[InterfaceType]在.NET属性来获得相同的:

No, lots of subtle mistakes that will get you into trouble. First off, the c++ interface declares a dual interface, supporting both early binding and late binding through IDispatch. You have to use the [InterfaceType] attribute in .NET to get the same:

[ComVisible(true)]
[Guid("xxxx")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ItsSupplier {
    [DispId(1)]
    string Name { get; }
}

请务必使用的确切的GUID相同,这是不是在你的代码片段可见。在[的MarshalAs]属性是不必要的,该字符串已经乘警为BSTR。

Be sure to use the exact same guid, it wasn't visible in your snippet. The [MarshalAs] attribute is unnecessary, the string already marshals as a BSTR.

接下来是类。你做的没有的要公开的类实现。强制客户端code也提防System.Object的,所有的.NET类的基类。它会出现在类型库中。使用[ComSourceInterfaces]是不正确,即应只适用于调度接口为事件

Next is the class. You do not want to expose the class implementation. That forces the client code to also beware of System.Object, the base class of all .NET classes. It will appear in the type library. Using [ComSourceInterfaces] is incorrect, that should only be applied to dispinterfaces for events.

[ComVisible(true)]
[Guid("xxxx")]
[ClassInterface(ClassInterfaceType.None)]
public class SupplierClass : ItsSupplier
{
    public string Name {
        get { return "someName"; }
    }
}

如在IDL文件中使用

再次使用的确切的GUID相同。其次是注册。使用注册为COM互操作选项是不错,但随后做的没有的再次运行Regasm.exe。你会搞糟登记的。如果你这样做preFER手工登记,然后始终使用/ codeBase的选项,这样的程序集没有被安装在GAC。

Again use the exact same guid as used in the IDL file. Next is registration. Using the "Register for COM interop" option is fine but then do not run Regasm.exe again. You'll mess up the registration with that. If you do prefer to register by hand then always use the /codebase option so the assembly doesn't have to be installed in the GAC.

这是你得到的一切的最终检查权是创建类型库与Tlbexp.exe并查看其与OLEView.exe这类,文件+查看类型库。它应该是你的IDL完全匹配。

The ultimate check that you got everything right is to create the type library with Tlbexp.exe and view it with Oleview.exe, File + View Typelib. It should be an exact match with your IDL.

这篇关于.NET实施的C ++接口,暴露于COM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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