VB6变体类型到.NET类型

时间:2010-07-13 19:19:52

标签: c# vb.net vb6 interop com-interop

我有一些无法轻易修改的VB6代码,如下所示:

Dim cCount as Long
Dim rCount as Long
Dim result()

Set mx = CreateObject("Component.Class")
Dim rtn = mx.GetList(rCount,cCount,result)

它调用的方法当前是一个VB6组件,我们已经迁移到.NET,只有一个问题。我们不确定result()正在寻找什么类型,因为它是变体类型。我们尝试过object,object [],object [] [],string,string []等,但都没有。

以下是一个例子:

public bool GetList(ref long rCount, ref long cCount, ref object result)
{
  ...
}

我甚至尝试将第三个参数设置为VariantWrapper,因为它会根据需要添加ByRef:

public bool GetList(ref long rCount, ref long cCount, VariantWrapper result)
{
  ...
}

我可以设置传入结果的任何想法,以便我没有未处理的异常吗?

我已经创建了一个测试接口(用于COM),测试类和测试VB6应用程序,以确保它是Variant的一个问题。所以,它的定义如下:

.NET接口:

[DispId(1)]
[ComVisible(true)]
string Test(ref object[] value);

VB 6方法:

Private Sub Command1_Click()
    Set mx = CreateObject("Component.Class")
    Dim result()
    MsgBox mx.Test(result)
End Sub

与上述相同的问题。在VB6中,它只是抛弃了我。如果我编译并运行它,我会得到一个通用的.NET异常,它会把我抛弃。

4 个答案:

答案 0 :(得分:4)

你的C#声明是错误的。由于历史原因,VB6“Long”是32位。这是C#方面的一个int。如果堆栈帧错误,则无法正确传递“result”参数。

它应该是变量的SafeArray,C#中的object []。

答案 1 :(得分:1)

mx.GetList(rCount,cCount,result)行放置一个断点。点击后,添加mx.GetList(rCount,cCount,result)的“快速观看”表达式。工具窗口应该显示生成的运行时类型是什么。很可能它是一个“comresult”并且不会提供太多信息,但它可能会提供返回类型的提示。

答案 2 :(得分:1)

我认为ref关键字可能会在这里造成一些麻烦。这些类型必须完全匹配才能发挥作用。

但是,如果您的方法仅接受对的任何object的引用(而不是ref),则可以传递任何内容,因为所有内容都来自.NET中的object

这个转换为VB6 / COM互操作的程度,我不知道。但似乎这至少值得一试:

C#代码

public string GetTypeName(object value)
{
    return value.GetType().FullName;
}

VB6代码

Set mx = CreateObject("Component.Class")
Dim result()

MsgBox mx.GetTypeName(result)

这会给你什么吗?


这是一个想法。我在这里可能会出错 - 我在将VB6应用程序迁移到.NET方面没有多少经验 - 但在我看来,如果你能够达到(C#相当于)这一行......

Set mx = CreateObject("Component.Class")

......那你就是金色的。您可以使用反射来确定GetList方法想要的参数。

首先获取表示System.Type类型的mx对象:

Type mxType = mx.GetType();

然后找到该类型的GetList方法:

MethodInfo[] getListMethods = mxType.GetMember("GetList")
    .OfType<MethodInfo>()
    .Where(m => m.GetParameters().Length == 3)
    .ToArray();

这将为您提供MethodInfo[]数组,其中包含3个参数的GetList的所有公共重载。从这里result的可能类型将是:

Type[] possibleResultTypes = getListMethods
    .Select(m => m.GetParameters()[2].ParameterType)
    .ToArray();

答案 3 :(得分:0)

我只知道在.Net中如何使用它来传递对Variant的引用,如下所示:

 int port = 2;
 object pvPort = new System.Runtime.InteropServices.VariantWrapper(port);
 gimp.SetPort(ref pvPort);

在此之后,如果您不确定,请设置断点并检查变体类型。

主要是使用VariantWrapper所以dll理解。