关于C#如何使用Prodave实战DllImport.docx

上传人:b****1 文档编号:11013771 上传时间:2023-05-28 格式:DOCX 页数:16 大小:21.43KB
下载 相关 举报
关于C#如何使用Prodave实战DllImport.docx_第1页
第1页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第2页
第2页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第3页
第3页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第4页
第4页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第5页
第5页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第6页
第6页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第7页
第7页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第8页
第8页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第9页
第9页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第10页
第10页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第11页
第11页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第12页
第12页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第13页
第13页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第14页
第14页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第15页
第15页 / 共16页
关于C#如何使用Prodave实战DllImport.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

关于C#如何使用Prodave实战DllImport.docx

《关于C#如何使用Prodave实战DllImport.docx》由会员分享,可在线阅读,更多相关《关于C#如何使用Prodave实战DllImport.docx(16页珍藏版)》请在冰点文库上搜索。

关于C#如何使用Prodave实战DllImport.docx

关于C#如何使用Prodave实战DllImport

严格意义上讲,此文不算OPC的范畴。

起因是,另一个项目的PLC强人说,OPC慢,用prodave吧,好,用就用吧,装好Prodave看是看其英文资料,虽然英文不好,但好在这里英文

很简单。

好了,上网查了点资料,这里还要感谢几个朋友的帮忙,让我对于C#与C++的数据结构有了更进一步的认识,也学会了使用DllImport

在本文的开头,我要说明下,Prodave是西门子的通信方式,即使我提供了Prodave6.dll,您不注册也是没用用的,所以请使用西门子的安装程序,哪里下载?

自己XX一下。

要来问我哪里下载Prodave6.dll,也不要问我为什么程序会报错说没有注册dll

下面开始进入正文。

(1)上来第一个函数,就是连接PLC的LoadConnection_ex6,在说明书里描述如下:

LoadConnection_ex6

ThebasicLoadConnection_ex6functioninitializestheadapter,checksifthe

driverisloaded,initializestheaddressesthathavebeenassignedparametersand

activatestheselectedinterface.

LoadConnection_ex6isusedtosetupatransportconnectionviaMPI/PB-orIP

addresses(TCP/IPprotocol)

intLoadConnection_ex6(intConNr,char*pAccessPoint,intConTableLen,

CON_TABLE_TYPE*pConTable);

Parameters

ConNr

[in]Numberoftheconnection(max.64connections).

pAccessPoint

[in]accesspoint(zero-terminated)ofthedriverused,e.g."S7ONLINE"fortheMPI

driveror0(default).

ConTableLen

[in]lengthofthetableofconnectionsprovidedbytheuserinbytes

pConTable

[in]pointertoaddresslistofconnectedusers;‘Adr==0’istakenastheendmarkof

thelist.

#pragmapack

(1)

typedefunion{

unsignedcharMpi;//MPI/PBstationaddress

(2)

unsignedcharIp[4];//IPaddress(192.168.0.1)

unsignedcharMac[6];//MACaddress(08-00-06-01-AA-BB)

}CON_ADR_TYPE;

typedefstruct{

CON_ADR_TYPEAdr;//connectionaddress

unsignedcharAdrType;//Typeofaddress:

MPI/PB

(1),IP

(2),MAC(3)

unsignedcharSlotNr;//Slotnumber

unsignedcharRackNr;//Racknumber

}CON_TABLE_TYPE;

#pragmapack

(1)

好吧,起先其他的转换网上都有,不难,但是出现了union共用体,恩C#没有这个概念。

怎么办?

起先,参考网上的资料,采用

[StructLayout(LayoutKind.Explicit)]

structS1

{

[FieldOffset(0)]

inta;

[FieldOffset(0)]

intb;

}

类似这样的布局,再加上类似[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]的声明。

但是,最终单纯的使用2个数组作为“共用体”字段的话是可以通过编译的,但是再加上unsignedcharMpi的话,OK你是过不了编译的,就算过了运行也出错。

反复尝试还是失败

,最后我联想到在内存中实际上这个共用体用的是一个以最大字段为空间大小的内存,于是乎尝试了,直接定义[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]byte

Mac[6],果然解决了,共用体的问题,其实C++传进去的参数也其实是6字节的数组而已,进而想既然一个数组搞定,那么还用共用体干嘛,不要了,于是出现了如下函数转换的正

解:

publicstructCON_TABLE_TYPE//待连接plc地址属性表

{

[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]

//publicCON_ADR_TYPEAdr;//connectionaddress

publicbyte[]Adr;//connectionaddress

//MPI/PBstationaddress

(2)

//IPaddress(192.168.0.1)

//MACaddress(08-00-06-01-AA-BB)

publicbyteAdrType;//Typeofaddress:

MPI/PB

(1),IP

(2),MAC(3)

publicbyteSlotNr;//Slotnumber

publicbyteRackNr;//Racknumber

}

[DllImport("Prodave6.dll")]//连接PLC操作

//参数:

连接号(0-63)、常值"S7ONLINE"、待连接plc地址属性表长度(字节为单位,常值9)、待连接plc地址属性表

publicexternstaticintLoadConnection_ex6(intConNr,stringpAccessPoint,intConTableLen,refCON_TABLE_TYPEpConTable);

(2)关于unsignedchar*pBuffer,这个unsignedchar*其实有2个转换可选,有时可以使用byte[],有时则是StringBuilder,这就要集体问题具体分析了。

例如:

intGetErrorMessage_ex6(intErrorNr,unsignedlongBufLen,unsignedchar*pBuffer);

voidcopy_buffer_ex6(unsignedchar*pTargetBuffer,unsignedchar*pSourceBuffer,unsignedlongAmount);

前者就转换成StringBuilder后者是byte[]。

(3)有些变量虽是整型但是可以用枚举,而且用枚举感觉更合适

例如intdb_read_ex6(unsignedshortBlkNr,unsignedcharDatType,unsigned

shortStartNr,unsignedlong*pAmount,unsignedlongBufLen,unsigned

char*pReadBuffer,unsignedlong*pDatLen)中,unsignedcharDatType其实指的是“0x02=BYTE,0x04=WORD,0x06=DWORDdefault:

DatType=0x02”等数据类型

,因此可以翻译成

publicenumDatType:

byte//PLC数据类型

{

BYTE=0x02,

WORD=0x04,

DWORD=0x06,

}

(4)对了,如果是对象型的引用,比如unsignedchar*转成byte[],是不需要加ref,但如果是c++int转c#int则要加ref关键字。

要说明的就是这些,下面请各位看官看看我的转换代码吧,还请见教:

publicclassProdave6

{

#region常值定义(用于极限值)

publicconstintMAX_CONNECTIONS=64;//64isdefaultinPRODAVE

publicconstintMAX_DEVNAME_LEN=128;//e.g."S7ONLINE"

publicconstintMAX_BUFFERS=64;//64forblk_read()andblk_write()

publicconstintMAX_BUFFER=65536;//Transferbufferforerrortext)

#endregion

#region结构体定义

publicstructCON_TABLE_TYPE//待连接plc地址属性表

{

[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]

//publicCON_ADR_TYPEAdr;//connectionaddress

publicbyte[]Adr;//connectionaddress

//MPI/PBstationaddress

(2)

//IPaddress(192.168.0.1)

//MACaddress(08-00-06-01-AA-BB)

publicbyteAdrType;//Typeofaddress:

MPI/PB

(1),IP

(2),MAC(3)

publicbyteSlotNr;//Slotnumber

publicbyteRackNr;//Racknumber

}

publicenumDatType:

byte//PLC数据类型

{

BYTE=0x02,

WORD=0x04,

DWORD=0x06,

}

publicenumFieldType:

byte//PLC区域类型

{

//ValuetypesasASCIIcharacters区域类型对应的ASCII字符

//databyte(d/D)

d=100,

D=68,

//inputbyte(e/E)

e=101,

E=69,

//outputbyte(a/A)

a=97,

A=65,

//memorybyte(m/M)

m=109,

M=77,

//timerword(t/T),

t=116,

T=84,

}

#endregion

#regionPLC基本函数

[DllImport("Prodave6.dll")]//连接PLC操作

//参数:

连接号(0-63)、常值"S7ONLINE"、待连接plc地址属性表长度(字节为单位,常值9)、待连接plc地址属性表

publicexternstaticintLoadConnection_ex6(intConNr,stringpAccessPoint,intConTableLen,refCON_TABLE_TYPEpConTable);

[DllImport("Prodave6.dll")]//断开PLC操作

//参数:

连接号(0-63)

publicexternstaticintUnloadConnection_ex6(UInt16ConNr);

[DllImport("Prodave6.dll")]//激活PLC连接操作

//参数:

连接号(0-63)

publicexternstaticintSetActiveConnection_ex6(UInt16ConNr);

[DllImport("Prodave6.dll")]//PLCdb区读取操作

//参数:

datablock号、要读取的数据类型、起始地址号、需要读取类型的数量、缓冲区长度(字节为单位)、缓冲区、缓冲区数据交互的长度

publicexternstaticintdb_read_ex6(UInt16BlkNr,DatTypeDType,UInt16StartNr,refUInt32pAmount,UInt32BufLen,

byte[]pBuffer,refUInt32pDatLen);

[DllImport("Prodave6.dll")]//PLCdb区写入操作

//参数:

datablock号、要写入的数据类型、起始地址号、需要写入类型的数量、缓冲区长度(字节为单位)、缓冲区

publicexternstaticintdb_write_ex6(UInt16BlkNr,DatTypeType,UInt16StartNr,refUInt32pAmount,UInt32BufLen,

byte[]pBuffer);

[DllImport("Prodave6.dll")]//PLC任意区读取操作

//参数:

要读取的区类型、datablock号(DB区特有,默认为0)、起始地址号、需要读取类型的数量、

//缓冲区长度(字节为单位)、缓冲区、缓冲区数据交互的长度

publicexternstaticintfield_read_ex6(FieldTypeFType,UInt16BlkNr,UInt16StartNr,UInt32pAmount,UInt32BufLen,

byte[]pBuffer,refUInt32pDatLen);

[DllImport("Prodave6.dll")]//PLC任意区写入操作

//参数:

要写入的区类型、datablock号(DB区特有,默认为0)、起始地址号、需要写入类型的数量、

//缓冲区长度(字节为单位)、缓冲区

publicexternstaticintfield_write_ex6(FieldTypeFType,UInt16BlkNr,UInt16StartNr,UInt32pAmount,UInt32BufLen,

byte[]pBuffer);

[DllImport("Prodave6.dll")]//PLCM区某字节的某位读取操作

//参数:

M区字节号、位号、当前的值(0/1)

publicexternstaticintmb_bittest_ex6(UInt16MbNr,UInt16BitNr,refintpValue);

[DllImport("Prodave6.dll")]//PLCM区某字节的某位写入操作

//参数:

M区字节号、位号、要写入的值(0/1)

publicexternstaticintmb_setbit_ex6(UInt16MbNr,UInt16BitNr,byteValue);

#endregion

#regionPLC200用数据传输函数

[DllImport("Prodave6.dll")]//200系列PLC任意区读取操作

//参数:

要读取的区类型、datablock号(DB区特有,默认为0)、起始地址号、需要读取类型的数量、

//缓冲区长度(字节为单位)、缓冲区、缓冲区数据交互的长度

publicexternstaticintas200_field_read_ex6(FieldTypeFType,UInt16BlkNr,UInt16StartNr,UInt32pAmount,UInt32BufLen,

byte[]pBuffer,refUInt32pDatLen);

[DllImport("Prodave6.dll")]//200系列PLC任意区写入操作

//参数:

要写入的区类型、datablock号(DB区特有,默认为0)、起始地址号、需要写入类型的数量、

//缓冲区长度(字节为单位)、缓冲区

publicexternstaticintas200_field_write_ex6(FieldTypeFType,UInt16BlkNr,UInt16StartNr,UInt32pAmount,UInt32BufLen,

byte[]pBuffer);

[DllImport("Prodave6.dll")]//200系列PLCM区某字节的某位读取操作

//参数:

M区字节号、位号、当前的值(0/1)

publicexternstaticintas200_mb_bittest_ex6(UInt16MbNr,UInt16BitNr,refintpValue);

[DllImport("Prodave6.dll")]//200系列PLCM区某字节的某位写入操作

//参数:

M区字节号、位号、要写入的值(0/1)

publicexternstaticintas200_mb_setbit_ex6(UInt16MbNr,UInt16BitNr,byteValue);

#endregion

#regionPLC数据转换函数

[DllImport("Prodave6.dll")]//诊断错误信息操作

//参数:

错误代号、缓冲区大小(字节为单位)、缓冲区

publicexternstaticintGetErrorMessage_ex6(intErrorNr,UInt32BufLen,[MarshalAs(UnmanagedType.LPStr)]StringBuilderpBuffer);

[DllImport("Prodave6.dll")]//S7浮点数转换成PC浮点数

//参数:

S7浮点数、PC浮点数

publicexternstaticintgp_2_float_ex6(UInt32gp,reffloatpieee);

[DllImport("Prodave6.dll")]//PC浮点数转换成S7浮点数

//参数:

PC浮点数、S7浮点数

publicexternstaticintfloat_2_gp_ex6(floatieee,refUInt32pgp);

[DllImport("Prodave6.dll")]//检测某字节的某位的值是0或1

//参数:

字节值、位号

publicexternstaticinttestbit_ex6(byteValue,intBitNr);

[DllImport("Prodave6.dll")]//检测某字节的byte值转换成int数组

//参数:

byte值、int数组(长度为8)

publicexternstaticvoidbyte_2_bool_ex6(byteValue,int[]pBuffer);

[DllImport("Prodave6.dll")]//检测某字节的int数组转换成byte值

//参数:

int数组(长度为8)

publicexternstaticbytebool_2_byte_ex6(int[]pBuffer);

[DllImport("Prodave6.dll")]//交换数据的高低字节——16位数据

//参数:

待交换的数据

publicexternstaticUInt16kf_2_integer_ex6(UInt16wValue);//16位数据——WORD

[DllImport("Prodave6.dll")]//交换数据的高低字节——32位数据

//参数:

待交换的数据

publicexternstaticUInt32kf_2_long_ex6(UInt32dwValue);//32位数据——DWORD

[DllImport("Prodave6.dll")]//交换数据缓冲区的的高低字节区,例如pBuffer[0]与pBuffer[1],pBuffer[2]与pBuffer[3]交换

//参数:

待交换的数据缓冲区,要交换的字节数,如Amount=pBuffer.Length,则交换全部缓冲

publicexternstaticvoidswab_buffer_ex6(byte[]pBuffer,UInt32Amount);

[DllImport("Prodave6.dll")]//复制数据缓冲区

//参数:

目的数据缓冲区,源数据缓冲区,要复制的数量(字节为单位)

publicexternstaticvoidcopy_buffer_ex6(byte[]pTargetBuffer,byte[]pSourceBuffer,UInt32Amount);

[DllImport("Prodave6.dll")]//把二进制数组传换成BCD码的数组——16位数据

//参数:

要处理的数组,要处理的字节数,转换前是否先交换高低字节,转换后是否要交换高低字节

//InBytechange为1则转换BCD码之前,先交换高低字节

//OutBytechange为1则转换BCD码之后,再交换高低字节

//如果InBytechange和OutBytechange都没有置1,则不发生高低位的交换

//16位数据BCD码值的许可范围是:

+999——-999

publicexternstaticvoidushort_2_bcd_ex6(UInt16[]pwValues,UInt32Amount,intInBytechange,intOutBytechange);//16位数据——WORD

[DllImport("Prodave6.dll")]//把二进制数组传换成BCD码的数组——32位数据

//参数:

要处理的数组,要处理的字节数,转换前是否先交换高低字节,转换后是否要交换高低字节

//InBytechange为1则转换BCD码之前,先交换高低字节

//OutBytechange为1则转换BCD码之后,再交换高低字节

//如果InBytechange和OutBytechange都没有置1,则不发生高低位的交换

//32位数据BCD码值的许可范围是:

+9999999——-9999999

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2