Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# VB6变体类型到.NET类型_C#_Vb.net_Vb6_Interop_Com Interop - Fatal编程技术网

C# VB6变体类型到.NET类型

C# VB6变体类型到.NET类型,c#,vb.net,vb6,interop,com-interop,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) int port = 2; object pvPort = new System.Runtime.InteropServices.VariantWrapper(port); g

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

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

Set mx = CreateObject("Component.Class")
Dim rtn = mx.GetList(rCount,cCount,result)
 int port = 2;
 object pvPort = new System.Runtime.InteropServices.VariantWrapper(port);
 gimp.SetPort(ref pvPort);
它调用的方法当前是一个VB6组件,我们已迁移到.NET,但有一个问题。我们不确定结果要查找什么类型,因为它是一种变体类型。我们尝试过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应用程序创建了一个测试接口,以确保它与变体有关。所以,它的定义如下:

.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异常,它会将我抛出。

在mx.GetListrCount、cCount、结果行上放置一个断点。点击后,添加mx.GetListrCount、cCount、result的快速观察表达式。工具窗口应该向您显示生成的运行时类型。很可能这是一个comresult,不会提供太多信息,但它可能会为返回类型提供提示。

我认为ref关键字可能会在这里造成一些问题。这些类型必须完全匹配才能工作

然而,如果您的方法只是通过值而不是通过ref接受对任何对象的引用,那么它可以传递任何内容,因为所有内容都来自.NET中的对象

我不知道如何将其转换为VB6/COM互操作。但这似乎至少值得一试:

C代码:

VB6代码:

这对你有什么帮助吗

有个主意。在这里我可能大错特错了——我在将VB6应用程序迁移到.NET方面没有太多经验——但在我看来,如果你能做到与这一行相当的C语言

Set mx = CreateObject("Component.Class")
…那你就是黄金。您可以使用反射来确定GetList方法需要哪些参数

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

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

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

你的C声明是错误的。由于历史原因,VB6的长度为32位。这是C端的整数。如果堆栈帧错误,则无法正确传递结果参数


它应该是一个变体的安全数组,C中的object[]我只知道它在.Net中是如何使用的,在.Net中,您可以传递一个对变体的引用,如下所示:

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

Set mx = CreateObject("Component.Class")
Dim rtn = mx.GetList(rCount,cCount,result)
 int port = 2;
 object pvPort = new System.Runtime.InteropServices.VariantWrapper(port);
 gimp.SetPort(ref pvPort);
在此之后,放置一个断点并检查变量类型(如果不确定)


最主要的是使用VariantWrapper,以便dll能够理解。

您可以看到结果是如何声明和传递的,但不能看到在GetList返回后它是如何使用的?同样,当变量类型被分配给result并传递到GetList时,.NET爆炸出一个错误。添加VarietRapper会给我一个错误5非法过程调用。请查看.NET中的反射,以执行以前在VB6中使用后期绑定所做的操作。我已将问题提交给VB团队。据我所知,他们认为我所做的应该有用。所以我向他们提交了一个完整的项目。我将在这里发回他们的响应。我已经修改了代码,这样一旦找到方法,它就会返回一个真正的布尔值。如果我将结果变量切换到不同的类型,并在快速VB6测试应用程序中测试它,它工作得很好。这不会起作用,因为VB6应用程序正在传递到C。这不是我需要在VB6中使用什么类型的问题,因为它是在C中设置COM方法的类型。VB6类型是可变的。C类型应该是object[]或VariantWrapper,两者都不能工作。@Jason:我想我弄糊涂了。你是说引发异常的是你的VB6代码吗?您只是想知道如何定义C方法,以便可以从VB6调用它?或者这是向后的?我想弄清楚如何定义我的C方法,以便可以从VB6调用它。然而,VB6并没有抛出异常,它是.NET。调用转到Interop中的类库,但由于它是.NET程序集,.NET生成异常。@Jason:我发布了另一个想法。让我知道这是否对你有用。我可能甚至不应该给我提供帮助,因为我对VB6或COM互操作几乎一无所知,但我对这个问题很感兴趣,所以我只是抛开我的想法;但它仍然不起作用。我马上收到一个.NET异常。请不要让我猜测异常。Hans,抛出的异常是Visual Basic生成的异常。。。它只在结果变量类型中发生。我创建了一个新的.NET方法来测试下面是我的签名表单接口:string Testref object[]value;然后,我创建了一个测试VB6应用程序,如下所示:Private Sub Command1_Click Set mx=CreateObjectComponent.Class Dim result MsgBox mx.Testresult End Sub与上述问题相同。正如我所说
严格地说,它不喜欢变型。我需要一段时间才能启动那台旧机器。呜呜。我推荐一份奖金。
Type[] possibleResultTypes = getListMethods
    .Select(m => m.GetParameters()[2].ParameterType)
    .ToArray();
 int port = 2;
 object pvPort = new System.Runtime.InteropServices.VariantWrapper(port);
 gimp.SetPort(ref pvPort);