Exposing indexer like properties to COM

前端 未结 1 1944
滥情空心
滥情空心 2020-12-19 19:40

I have in existing COM-interface. I wan\'t to create a .net assembly that exposes a new interface as COM (with a new GUID), but the structure of the interface needs to be th

相关标签:
1条回答
  • 2020-12-19 20:38

    Your IDL isn't valid, an interface that is attributed with [oleautomation] should derive from IDispatch, not IUnknown. I'll give the proper declarations and hint where you need to modify them to get yours.

    You cannot declare indexed properties in C#, the C# team refuses to implement them. Version 4 has support for indexed properties that are declared in a COM type library but still doesn't allow declaring them yourself. The workaround is to use the VB.NET language, it has no qualms about it. Add a VB.NET class library project to your solution. Make it look similar to this:

    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
    

    Note the use of <DispId>, dispid 0 is special, it is the default property of an interface. This corresponds to the indexer in the C# language.

    All you need VB.NET for is the declaration, you can still write the implementation of the interface in the C# language. Project + Add Reference, Projects tab and select the VB.NET project. Make it look similar to this:

    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) {
            }
        }
    }
    

    You need to run Tlbexp.exe on both the VB.NET and the C# assembly to generate the type libraries. The C# one with the implementation includes the VB.NET one.

    To get the interface to derive from IUnknown instead of IDispatch, edit the interface declaration. Remove the DispId attributes and use ComInterfaceType.InterfaceIsUnknown.

    0 讨论(0)
提交回复
热议问题