我在VBSript中定义了一个类:
Class Foo
Public i
End Class
我想将一个实例传递给用C#编写的COM对象:
Dim oCOMTEST : Set oCOMTEST = CreateObject("COMTests.Class1")
Dim oFoo : Set oFoo = new Foo
oFoo.i = 42
Call oCOMTEST.M(oFoo)
方法M
定义为:
public void M(ref object foo)
目前该方法需要object
,但我宁愿使用该方法
采用C#等价类型的Foo
。其中我尝试过改变object
到Foo
,
[StructLayout(LayoutKind.Sequential)]
public class Foo
{
[MarshalAs(UnmanagedType.U4)]
public int i;
}
但没有成功。因此我的问题是:
VBScript类型Foo
的封送C#版本如何?
-
这是我的最小测试用例。
using System.Runtime.InteropServices;
namespace COMTests
{
[ComVisible(true)]
[Guid("4624071F-2D98-4ECC-8898-558F4D24EEC9")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IClass1
{
void M(ref object foo);
}
[ComVisible(true)]
[Guid("9F2B6958-742F-4E5D-A5F3-D6BDC6C841DB")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("COMTests.Class1")]
public class Class1 : IClass1
{
public void M(ref object foo)
{
System.Diagnostics.Debugger.Launch();
}
}
}
以下VBScript:
Dim oCOMTEST : Set oCOMTEST = CreateObject("COMTests.Class1")
Dim oFoo : Set oFoo = new Foo
oFoo.i = 42
Call oCOMTEST.M(oFoo)
Class Foo
Public i
End Class
答案 0 :(得分:3)
VBScript类不是完整的COM对象,因为它没有与之关联的IID(接口ID)。所以,我可能错了,但我不认为你可以让它与.NET类或接口匹配(许多属性,如ComImport
期望一个关联的Guid属性)。如果Foo是从“真正的”COM对象创建的,它可以工作。在后台,我相信VBScript的Foo对象只实现了IDispatch
,所以它本质上非常动态。
但是,您仍然可以使用c#dynamic
伪类型关键字轻松使用其属性和元数据,例如,以下代码应该可以正常工作:
[ComVisible(true)]
[Guid("9F2B6958-742F-4E5D-A5F3-D6BDC6C841DB")]
[ProgId("COMTests.Class1")]
public class Class1
{
public void M(dynamic foo)
{
Console.WriteLine("foo:" + foo.i);
}
}
PS:在此上下文中不需要接口或ref属性。使用上面的代码,这将由.NET自动创建(在IDL术语中,为了便于阅读,有点简化):
[
uuid(E66DC08B-A63A-41A8-B63D-15ED6F4569AB),
version(1.0),
]
library ClassLibrary1
{
interface _Class1;
[
uuid(9F2B6958-742F-4E5D-A5F3-D6BDC6C841DB),
version(1.0),
]
coclass Class1 {
[default] interface _Class1;
interface _Object;
};
[
odl,
uuid(F56AF0FC-D93B-399E-8FBD-9B72CF50D7D9),
hidden,
dual,
oleautomation,
]
interface _Class1 : IDispatch {
};
};