[英]How to expose an enum defined in a COM library via interop as the return type of a c# function
希望問題很清楚,但為了清楚起見,請將其填寫清楚:
我有一個VB6 dll定義了我在C#dll中引用的枚舉。 C#dll以正確的方式定義CCW,其中idispatch接口聲明了一個函數,其返回類型是枚舉。
運行regasm時,我收到一個警告,表明枚舉不是COM可見,因此不會導出該函數。 因為它是在我的VB6庫中定義的,所以我認為它已經是COM可見的,因為它是在COM dll中定義的。
我意識到我可以停止搞亂並使用一個int傳遞枚舉,只是做任何一個結束,但它是適當的令人沮喪,我想知道是否存在一種方式。
根據要求,這里有一些示例代碼:
VB6 dll定義了一個枚舉
Public Enum myEnum
first = 0
second = 1
End Enum
這通過interop導入到C#中,如果您查看元數據,它看起來像這樣
[Guid("EnumGUID")]
public enum myEnum
{
first = 0,
second = 1
}
然后定義CCW接口
[ComVisible(true)]
[Guid("InterfaceGuid")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMyCCWInterface
{
[DispId(1)]
myEnum myFunction();
}
Regasm抱怨myEnum不可見。 我必須同意它,因為元數據視圖沒有com visible屬性。 奇怪的是,如果我在VB dll中使用其他類型定義函數的參數我沒有抱怨,它似乎是枚舉,我猜它是因為我實際上暴露了VB6枚舉的交錯實現而不是實際的枚舉。
所以我想我理解這個問題,我想知道的是,如果有一種方法可以使用不涉及黑客攻擊任何中間或自動生成的代碼的枚舉。
看起來解決方案是在C#項目中為導入的COM程序集設置“嵌入互操作類型”屬性為False。
為了測試這個,我創建了一個VB COM dll作為StackOverflow.ExampleCom
其中包含以下代碼
Public Enum EThing
eThingOne = 1
eThingTwo = 2
End Enum
Private mThing As EThing
Private Sub Class_Initialize()
mThing = eThingOne
End Sub
Public Property Let Thing(newVal As EThing)
mThing = newVal
End Property
Public Property Get Thing() As EThing
Thing = mThing
End Property
然后我創建了一個C#類項目並導入了這個StackOverflow COM庫。 然后,C#中的以下代碼創建一個COM對象,該對象重新公開VB代碼中定義的枚舉類型,從而創建OP描述的相同情況。
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using StackOverflow;
namespace EnumDemo
{
[ComVisible(true)]
[Guid("c30d35fe-2c7f-448b-98be-bd9be567ce70")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IEnumDemo
{
[DispId(1)]
EThing Thing
{
get;set;
}
}
[ComVisible(true)]
[Guid("af328c82-08e3-403e-a248-8c46e27b48f3")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("StackOverflow.EnumDemo")]
public class EnumDemo
{
private EThing mThing = EThing.eThingOne;
public EThing Thing { get { return mThing; } set { mThing = value; } }
}
}
如果我們構建它然后嘗試使用regasm /tlb:EnumDemo.tlb bin\\Debug\\EnumDemo.dll
從此程序集創建一個類型庫,然后我收到有關使用非COM可見值類型的警告。 但是,一旦對VB COM dll的引用將“嵌入互操作類型”設置為false,警告就會消失,並且使用OleView檢查生成的類型庫會顯示正在使用該類型,並且已添加importlib
以引用原始dll。
library EnumDemo
{
// TLib : // TLib : : {D482D5CB-EE6C-455A-A28A-D26A5AC579D5}
importlib("StackOverflow.dll");
// TLib : mscorlib.dll : {BED7F4EA-1A96-11D2-8F08-00A0C9A6186D}
...
interface IEnumDemo : IDispatch {
[id(0x00000001), propget]
HRESULT Thing([out, retval] EThing* pRetVal);
[id(0x00000001), propput]
HRESULT Thing([in] EThing pRetVal);
};
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.