简体   繁体   English

从C#.Net 2010 Pinvoke VB6函数

[英]Pinvoke a VB6 function from C#.Net 2010

I want to PInvoke a function written in VB6 from C#. 我想从C#中调用用VB6编写的函数。 We can call this function in VB6 like this: 我们可以这样在VB6中调用此函数:

Declare Function ApplyNNet Lib " location of the DLL file" (MyNNetType As String, MyAddress As String, MyInput() As Double) As Variant

My code in C# is: 我在C#中的代码是:

[DllImport("NNetApply.dll", EntryPoint = "ApplyNNet", CallingConvention = CallingConvention.StdCall)] 
public static extern IntPtr ApplyNNet(string type, string add, double[,] data);
//run ANN with data
string address = @"C:\Users\PNGE-User\Desktop\Faegheh\Project\Neural Network For Pressure Vs q,x,y\P ve x,y,q\P ve x,y,q";
        double[,] P = new double[no_data,2];
        var P_ = ApplyNNet("Back Prop", address, data);

When I debug my code, an error appears: 当我调试代码时,出现错误:

Attempted to read or write protected memory. 尝试读取或写入受保护的内存。 This is often an indication that other memory is corrupt. 这通常表明其他内存已损坏。

First of all, I am assuming that the DLL was not in fact written in VB6. 首先,我假设DLL实际上不是用VB6编写的。 The fact that you show code that uses Declare to call the function contradicts that. 您显示使用Declare调用函数的代码的事实与此矛盾。 So I am assuming that the DLL was written in some other language (eg C++) and that you are currently calling the DLL from VB6. 因此,我假设DLL是用其他某种语言(例如C ++)编写的,并且您当前正在从VB6调用DLL。

The VB6 code that calls the DLL is declared like this: 调用DLL的VB6代码如下声明:

Declare Function ApplyNNet Lib "DLLFileName" (MyNNetType As String,
    MyAddress As String, MyInput() As Double) As Variant

Your C# version looks like this: 您的C#版本如下所示:

[DllImport("NNetApply.dll", EntryPoint = "ApplyNNet", 
    CallingConvention = CallingConvention.StdCall)] 
public static extern IntPtr ApplyNNet(string type, string add, double[,] data);

There are two obvious differences: 有两个明显的区别:

  1. The third parameter does not match. 第三个参数不匹配。 Instead of double[,] you need double[] . 代替double[,]您需要double[]
  2. The return value does not match. 返回值不匹配。 A VB6 variant cannot be matched up with IntPtr . VB6变体不能与IntPtr匹配。 You need to declare the return value to be of type object in your C# code. 您需要在C#代码中将返回值声明为object类型。

So the pinvoke should be: 因此,pinvoke应该是:

[DllImport("NNetApply.dll")] 
public static extern object ApplyNNet(string type, string add, double[] data);

Update 更新资料

With this declaration you receive a pinvoke error: 使用此声明,您会收到拼写错误:

PInvoke restriction: cannot return variants. PInvoke限制:无法返回变体。

I'm not sure how you can get around this in pinvoke. 我不确定您如何才能解决这个问题。 In your situation I think I would create a VB6 project that wrapped up the DLL and exposed it as a COM interface. 在您的情况下,我想我将创建一个VB6项目,该项目将DLL打包并将其公开为COM接口。 I'd then add a COM reference to your C# project and move on. 然后,将COM引用添加到您的C#项目并继续。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM