看来解决方案是将 C# 项目中导入的 COM 程序集的“Embed Interop Types”属性设置为 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);
};
...