【问题标题】:Exposing indexer like properties to COM向 COM 公开类似索引器的属性
【发布时间】:2011-09-21 02:20:02
【问题描述】:

我有现有的 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);

};

【问题讨论】:

    标签: c# com-interop idl


    【解决方案1】:

    您的 IDL 无效,带有[oleautomation] 属性的接口应该派生自 IDispatch,而不是 IUnknown。我会给出正确的声明并提示您需要修改它们以获得您的声明。

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

    Imports System.Runtime.InteropServices
    
    Namespace Mumble
    
        <ComVisible(True)> _
        <Guid("2352FDD4-F7C9-443a-BC3F-3EE230EF6C1B")> _
        <InterfaceType(ComInterfaceType.InterfaceIsDual)> _
        Public Interface IExample
            <DispId(0)> _
            Property Indexer(ByVal index As Integer) As Integer
            <DispId(1)> _
            Property SomeProperty(ByVal index As Integer) As String
        End Interface
    
    End Namespace
    

    注意&lt;DispId&gt;的使用,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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-10
      • 1970-01-01
      • 2010-12-31
      相关资源
      最近更新 更多