揭露索引像属性COM [英] Exposing indexer like properties to COM

查看:121
本文介绍了揭露索引像属性COM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在现有的COM接口。我wan't创建公开了新的界面,COM(具有新的GUID).NET程序集,但接口的结构必须一致。



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

  [
ODL,
UUID(1ED4C594-DDD7-402F-90DE-7F85D65560C4),
隐藏,
了oleautomation
]
接口_IFlashPhase:{IUnknown的

[propget子]
HRESULT _stdcall组件名(
[中]总之我,
[出来,RETVAL] BSTR * PVAL);
[propput]
HRESULT _stdcall组件名(
[中]总之我,
[中] BSTR PVAL);
[propget子]
HRESULT _stdcall ComponentMolePercent(
[中]总之我,
[出来,RETVAL]双* PVAL);
[propput]
HRESULT _stdcall ComponentMolePercent(
[中]总之我,
[中]双PVAL);
[propget子]
HRESULT _stdcall ComponentFugacity(
[中]总之我,
[出来,RETVAL]双* PVAL);
[propput]
HRESULT _stdcall ComponentFugacity(
[中]总之我,
[中]双PVAL);

};


解决方案

您IDL是无效的,这是一个接口使用[了oleautomation]应归功于从IDispatch接口派生,而不是IUnknown的。我给你需要对它们进行修改,以得到你适当的声明和提示。



您不能在C#中声明索引属性,C#团队拒绝执行。第4版拥有了在COM类型库中声明,但仍不允许自己宣布这些索引属性的支持。解决方法是使用VB.NET语言,它有没有关于它的疑虑。一个VB.NET类库项目添加到您的解决方案。使它看起来类似于这样:

 进口System.Runtime.InteropServices 

命名空间喃喃

<标记有ComVisible特性(真)> _
<的Guid(2352FDD4-F7C9-443a-BC3F-3EE230EF6C1B)> _
< InterfaceType(ComInterfaceType.InterfaceIsDual)GT; _
公用接口的IExample
< D​​ISPID(0)GT; _
属性索引(BYVAL指数为整数)作为整数
< D​​ISPID(1)> _
房产SomeProperty(BYVAL指数为整数)作为字符串
端接口

端命名空间

请注意使用<的; DISPID> ,DISPID 0是特殊的,它是一个接口的默认属性。这相当于在C#语言的索引器。



所有你需要VB.NET的是声明,你仍然可以写的实施的在C#语言的接口。项目+添加引用,项目选项卡,然后选择VB.NET工程。使它看起来类似于这样:

 使用系统;使用System.Runtime.InteropServices 
;

命名空间喃喃{
[标记有​​ComVisible特性(真)]
[的Guid(8B72CE6C-511F-456e-B71B-ED3B3A09A03C)]
[ClassInterface(ClassInterfaceType。无)]
耻骨类实现:ClassLibrary2.Mumble.IExample {
公众诠释get_Indexer(INT指数){
收益指数;
}
公共无效set_Indexer(INT指数,int值){
}

公共字符串get_SomeProperty(INT指数){
返回index.ToString( );
}

公共无效set_SomeProperty(INT指数,字符串值){
}
}
}

您需要在的两个的VB.NET的和C#程序集生成类型库运行Tlbexp.exe。 C#的一个具有实现包括VB.NET之一。



要获得接口从IUnknown的,而不是IDispatch接口派生,编辑的接口声明。取出DISPID属性和使用ComInterfaceType.InterfaceIsUnknown


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 the same.

How can i create a .net class (C#) that exposes this interface?

[
  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);

};

解决方案

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)]
    pubic 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

这篇关于揭露索引像属性COM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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