vb6.0 转c#遇到问题,不解,惶惶不可终日,SOS求救大虾支援

wo2007 2015-12-29 11:02:34
原来vb6.0代码
Declare Function OpenCom Lib "S7_200_PPI.dll" (ByVal ComNo As Long) As Long
Declare Function CloseCom Lib "S7_200_PPI.dll" () As Long
Declare Function SetBaudRate Lib "S7_200_PPI.dll" (ByVal BaudRate As Long) As Long
Declare Function bitsetV Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal bitNo As Long) As Long
Declare Function bitResetV Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal bitNo As Long) As Long
Declare Function bit Lib "S7_200_PPI.dll" (ByVal AByte As Byte, ByVal bitNo As Long) As Boolean
Declare Function readVB Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal length As Long, buff As Byte) As Long
Declare Function readVW Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal length As Long, buff As Integer) As Long
Declare Function writeVB Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal value As Byte) As Long
Declare Function writeVW Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal value As Integer) As Long
Declare Function PLCRUN Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long) As Long
Declare Function PLCSTOP Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long) As Long
Declare Sub setReadDelay Lib "S7_200_PPI.dll" (ByVal ADelayTime As Long)
Declare Sub setOKDelay Lib "S7_200_PPI.dll" (ByVal ADelayTime As Long)

    Dim rxdata(1024) As Integer
Dim tmp As String
Text1 = ""
If readVW(2, Val(Text8), Val(Text10), rxdata(0)) > 0 Then
tmp = ""
For i = 0 To Val(Text10) - 1
tmp = tmp & rxdata(i) & ","
Next
Text1 = tmp
Else
Text1 = "error"
End If

我转为c#
public class Api
{
private Api()
{
}
[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int OpenCom (Int32 ComNo);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int CloseCom ();

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int SetBaudRate (Int32 BaudRate);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int bitsetV (Int32 PLCaddr, Int32 Vaddr, Int32 bitNo);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int bitResetV (Int32 PLCaddr, Int32 Vaddr, Int32 bitNo);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int bit (byte AByte, Int32 bitNo);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int readVB (Int32 PLCaddr, Int32 Vaddr, Int32 length,Byte buff);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int readVW(Int32 PLCaddr, Int32 Vaddr, Int32 length, int buff);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int writeVB (Int32 PLCaddr, Int32 Vaddr, byte value);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int writeVW (Int32 PLCaddr, Int32 Vaddr, int value);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int PLCRUN (Int32 PLCaddr);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int PLCSTOP (Int32 PLCaddr);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int setReadDelay (Int32 ADelayTime);

[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int setOKDelay(Int32 ADelayTime);

}


//这句没问题
if (Api.OpenCom(5) > 0){
textBox1.Text = "打开成功";
}
else
{
textBox1.Text = "打开失败";
}

//这个报错,由于是调用dll,无法捕获异常,竟然弹出APPCRASH问题(vb下没问题)……
int[] rxdata = new int[1024];
string tmp;
textBox1.Text = "";
if (Api.readVW(2, 40, 10, rxdata[0]) > 0)
{
tmp = "";
for (int i = 0; i < 9; i++)
{
tmp = tmp+rxdata[i].ToString()+",";
}
}
else{
tmp = "读取错误";

}
textBox1.Text =tmp;

调试N边无解,本来直接可以用vb做个后台程序算了,但不知问题何解,实在是纠结不堪、心神不定、如坐针毡、心烦意乱、胆战心惊、提心吊胆、寝食难安、惶惶不可终日、求救各位大虾出手了,在这里谢谢各位乡亲父老了……
...全文
294 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
wo2007 2015-12-29
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
vb6的程序可以编译为一个 COM 组件,然后你的 c# 项目引用这个 COM 组件即可。.net可以直接调用vb所产生的com组件,不用做什么参数类型转换,因此就跟用c#写的class一样方便。(当然,在部署时就要自动在用户机器上注册COM组件)。 否则,最好用c#重写你的vb6的程序。是用你的设备厂商提供的.net 组件,而不用 S7_200_PPI.dll。
哦,做成COM 组件也可以吗?到时试试,这是西门子的plc,百度了下,没有相关的厂商控件,通信协议也太费时间去折腾了,就找了个网上的dll文件用用,其实网络上dll文件的安全和稳定问题也是个麻烦事
wo2007 2015-12-29
  • 打赏
  • 举报
回复
引用 2 楼 shingoscar 的回复:
Declare Function readVW Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal length As Long, buff As Integer) As Long
[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern short readVW(Int32 PLCaddr, Int32 Vaddr, Int32 length, short[] buff);
我拿这个说明下吧 vb里long对应c#int / Int32 vb里integer对应c#short / Int16 像buff这个参数是byref,对应到c#里直接用数组就行
我也是按照vb里long对应c#int / Int32,vb里integer对应c#short / Int16但没想到像buff这个参数是byref,对应到c#里直接用数组就行,原来是酱紫,我刚开始理解为从数组0依次写入,所以直接Api.readVW(2, 40, 10, rxdata[0]),谢谢,问题解决!
wo2007 2015-12-29
  • 打赏
  • 举报
回复
引用 1 楼 qbilbo 的回复:
声明:
[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int readVW(Int32 PLCaddr, Int32 Vaddr, Int32 length, IntPtr buff);
调用:
IntPtr p = Marshal.AllocHGlobal(1024);
if (Api.readVW(2, 40, 10, p) > 0)
{
        byte[] data = new byte[1024];
        Marshal.Copy(p, data, 0, 1024);
        ......
}
先这样试试。
托管内存这方法我不熟悉,我试了下,用foreach 取出data数据,第一组是对的,后面好像就不对了,不知道什么原因……谢了,已解决。
  • 打赏
  • 举报
回复
vb6的程序可以编译为一个 COM 组件,然后你的 c# 项目引用这个 COM 组件即可。.net可以直接调用vb所产生的com组件,不用做什么参数类型转换,因此就跟用c#写的class一样方便。(当然,在部署时就要自动在用户机器上注册COM组件)。 否则,最好用c#重写你的vb6的程序。是用你的设备厂商提供的.net 组件,而不用 S7_200_PPI.dll。
Poopaye 2015-12-29
  • 打赏
  • 举报
回复
Declare Function readVW Lib "S7_200_PPI.dll" (ByVal PLCaddr As Long, ByVal Vaddr As Long, ByVal length As Long, buff As Integer) As Long
[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern short readVW(Int32 PLCaddr, Int32 Vaddr, Int32 length, short[] buff);
我拿这个说明下吧 vb里long对应c#int / Int32 vb里integer对应c#short / Int16 像buff这个参数是byref,对应到c#里直接用数组就行
qbilbo 2015-12-29
  • 打赏
  • 举报
回复
声明:
[DllImport("S7_200_PPI.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int readVW(Int32 PLCaddr, Int32 Vaddr, Int32 length, IntPtr buff);
调用:
IntPtr p = Marshal.AllocHGlobal(1024);
if (Api.readVW(2, 40, 10, p) > 0)
{
        byte[] data = new byte[1024];
        Marshal.Copy(p, data, 0, 1024);
        ......
}
先这样试试。

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧