将类似索引器的属性暴露给COM

我有现有的COM界面。 我不想创建一个将新接口公开为COM(带有新GUID)的.net程序集,但接口的结构必须相同。

如何创建一个公开此接口的.net类(C#)?

[ odl, uuid(1ED4C594-DDD7-402F-90DE-7F85D65560C4), hidden, oleautomation ] interface _IFlashPhase : IUnknown { [propget] HRESULT _stdcall ComponentName( [in] short i, [out, retval] BSTR* pVal); [propput] HRESULT _stdcall ComponentName( [in] short i, [in] BSTR pVal); [propget] HRESULT _stdcall ComponentMolePercent( [in] short i, [out, retval] double* pVal); [propput] HRESULT _stdcall ComponentMolePercent( [in] short i, [in] double pVal); [propget] HRESULT _stdcall ComponentFugacity( [in] short i, [out, retval] double* pVal); [propput] HRESULT _stdcall ComponentFugacity( [in] short i, [in] double pVal); }; 

您的IDL无效,属于[oleautomation]的接口应该来自IDispatch,而不是IUnknown。 我将给出正确的声明并提示您需要修改它们以获取您的声明。

您无法在C#中声明索引属性,C#团队拒绝实现它们。 版本4支持在COM类型库中声明的索引属性,但仍然不允许自己声明它们。 解决方法是使用VB.NET语言,它没有任何疑虑。 将VB.NET类库项目添加到您的解决方案中。 使它看起来类似于:

 Imports System.Runtime.InteropServices Namespace Mumble  _  _  _ Public Interface IExample  _ Property Indexer(ByVal index As Integer) As Integer  _ Property SomeProperty(ByVal index As Integer) As String End Interface End Namespace 

注意使用 ,dispid 0是特殊的,它是接口的默认属性。 这对应于C#语言中的索引器。

所有你需要的VB.NET都是声明,你仍然可以用C#语言编写接口的实现 。 项目+添加参考,项目选项卡,然后选择VB.NET项目。 使它看起来类似于:

 using System; using System.Runtime.InteropServices; namespace Mumble { [ComVisible(true)] [Guid("8B72CE6C-511F-456e-B71B-ED3B3A09A03C")] [ClassInterface(ClassInterfaceType.None)] public class Implementation : ClassLibrary2.Mumble.IExample { public int get_Indexer(int index) { return index; } public void set_Indexer(int index, int Value) { } public string get_SomeProperty(int index) { return index.ToString(); } public void set_SomeProperty(int index, string Value) { } } } 

您需要在VB.NET和C#程序集上运行Tlbexp.exe以生成类型库。 实现的C#包括VB.NET。

要使接口从IUnknown而不是IDispatch派生,请编辑接口声明。 删除DispId属性并使用ComInterfaceType.InterfaceIsUnknown