我有现有的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);
};
答案 0 :(得分:7)
您的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
注意使用<DispId>
,dispid 0是特殊的,它是接口的默认属性。这对应于C#语言中的索引器。
您只需要声明VB.NET,您仍然可以用C#语言编写接口的实现。 Project + Add Reference,Projects选项卡并选择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) {
}
}
}
您需要在上运行Tlbexp.exe VB.NET和C#程序集以生成类型库。实现的C#包括VB.NET。
要从IUnknown而不是IDispatch派生接口,请编辑接口声明。删除DispId属性并使用ComInterfaceType.InterfaceIsUnknown