.NET实现的C++;接口,向COM公开

.NET实现的C++;接口,向COM公开,.net,c++,com,.net,C++,Com,我相信我的问题的答案是这个论坛上已经出现的许多帖子的组合。也许你能帮我把这些碎片拼起来 我的挑战是,我有一些C++代码,它实现了一个类似于这个接口的接口: interface ItsSupplier : IDispatch { [propget, id(1), helpstring("property name") HRESULT Name([out, retval] BSTR* pVal); } 实现此接口的DLL是第三方软件中的可用插件。 我想制作一个用.NET编写的插件。 由于使

我相信我的问题的答案是这个论坛上已经出现的许多帖子的组合。也许你能帮我把这些碎片拼起来

我的挑战是,我有一些C++代码,它实现了一个类似于这个接口的接口:

interface ItsSupplier : IDispatch {
    [propget, id(1), helpstring("property name") HRESULT Name([out, retval] BSTR* pVal);
}
实现此接口的DLL是第三方软件中的可用插件。 我想制作一个用.NET编写的插件。 由于使用插件的软件不是.NET,我认为DLL必须是COM对象

下面是我在.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”

生成后,我运行“regasm testDll.dll”

我的问题是

自己定义ITS供应商接口是否正确?我的意思是,这是一个第三方软件所期望的界面,所以它必须在其他地方被引用吗

当涉及到COM互操作部分时,我做得对吗

我希望我的解释是正确的:)

干杯 /托马斯

----------------汉斯回复后编辑------------------------

当我构建tlb文件并在Oleview中查看原始版本和我的版本时,这就是我得到的

以下是原始接口插件在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”是我的VisualStudio项目的名称。你认为这重要吗


/托马斯

不,很多细微的错误会给你带来麻烦。首先,C++接口声明了一个双接口,通过IDISP补丁支持早期绑定和后期绑定。您必须使用.NET中的[InterfaceType]属性才能获得相同的结果:

[ComVisible(true)]
[Guid("xxxx")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ItsSupplier {
    [DispId(1)]
    string Name { get; }
}
请确保使用完全相同的guid,它在代码段中不可见。[MarshalAs]属性是不必要的,字符串已经作为BSTR进行封送处理

接下来是课堂。您不想公开类实现。这迫使客户机代码还要注意System.Object,它是所有.NET类的基类。它将出现在类型库中。使用[ComSourceInterfaces]是不正确的,它只应用于事件的dispinterfaces

[ComVisible(true)]
[Guid("xxxx")]
[ClassInterface(ClassInterfaceType.None)]
public class SupplierClass : ItsSupplier
{
    public string Name {
        get { return "someName"; }
    }
}
再次使用与IDL文件中使用的完全相同的guid。接下来是注册。使用“注册COM互操作”选项可以,但不要再次运行Regasm.exe。你会把注册搞砸的。如果您确实喜欢手动注册,那么请始终使用/codebase选项,这样程序集就不必安装在GAC中


确保一切正常的最终检查是使用Tlbexp.exe创建类型库,并使用Oleview.exe、File+view Typelib查看它。它应该与您的IDL完全匹配。

嘿,汉斯,非常感谢您的输入,这确实澄清了一些事情。至于在Oleview中查看Tlb文件,那太棒了!请看一下我的答案,这是怎么回事。没关系,只是tlbexp.exe添加了一些额外的属性。您无法获取[helpstring]。这不是在SO提问的正确方式。开始一个新问题。