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

严格意义上讲,此文不算OPC的范畴。起因是,另一个项目的PLC强人说,OPC慢,用prodave吧,好,用就用吧,装好Prodave看是看其英文资料,虽然英文不好,但好在这里英文

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

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

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

下面开始进入正文。
(1)上来第一个函数,就是连接PLC的LoadConnection_ex6,在说明书里描述如下:
LoadConnection_ex6
The basic LoadConnection_ex6 function initializes the adapter, checks if the
driver is loaded, initializes the addresses that have been assigned parameters and
activates the selected interface.
LoadConnection_ex6 is used to set up a transport connection via MPI/PB- or IP
addresses (TCP/IP protocol)
int LoadConnection_ex6 (int ConNr, char* pAccessPoint, int ConTableLen,
CON_TABLE_TYPE * pConTable);
Parameters
ConNr
[in] Number of the connection (max. 64 connections).
pAccessPoint
[in] access point (zero-terminated) of the driver used, e.g. "S7ONLINE" for the MPI
driver or 0 (default).
ConTableLen
[in] length of the table of connections provided by the user in bytes
pConTable
[in] pointer to address list of connected users; ‘Adr ==0’ is taken as the end mark of
the list.
#pragma pack(1)
typedef union {
unsigned char Mpi; // MPI/PB station address (2)
unsigned char Ip[4]; // IP address (192.168.0.1)
unsigned char Mac[6]; // MAC address (08-00-06-01-AA-BB)
} CON_ADR_TYPE;
typedef struct {
CON_ADR_TYPE Adr; // connection address
unsigned char AdrType; // Type of address: MPI/PB (1), IP (2), MAC (3)
unsigned char SlotNr; // Slot number
unsigned char RackNr; // Rack number
} CON_TABLE_TYPE;
#pragma pack(1)

好吧,起先其他的转换网上都有,不难,但是出现了union共用体,恩C#没有这个概念。怎么办?起先,参考网上的资料,采用

[StructLayout(LayoutKind.Explicit)] 
struct S1 

[FieldOffset(
0)] 
int a; 
[FieldOffset(
0)] 
int b; 

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

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

解:

Code

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

int GetErrorMessage_ex6 (int ErrorNr, unsigned long BufLen, unsigned char* pBuffer);
void copy_buffer_ex6 (unsigned char * pTargetBuffer, unsigned char *pSourceBuffer, unsigned long Amount);

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

(3)有些变量虽是整型但是可以用枚举,而且用枚举感觉更合适
例如int db_read_ex6 (unsigned short BlkNr, unsigned char DatType, unsigned
short StartNr, unsigned long * pAmount, unsigned long BufLen, unsigned
char * pReadBuffer, unsigned long * pDatLen)中,unsigned char DatType其实指的是“0x02 = BYTE, 0x04 = WORD, 0x06 = DWORD default: DatType = 0x02”等数据类型
,因此可以翻译成

public enum DatType : byte//PLC数据类型
        {
            BYTE 
= 0x02,
            WORD 
= 0x04,
            DWORD 
= 0x06,
        }

 

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

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

Code

(6)最后,要说的是我没有转换全部的函数,只是挑了我认为比较常用的,或者我可能用的到的进行了转换。
详细的程序包,如果能要的话,可以去这里下载,同时还附带了英文版的prodave的pdf说明书哦:

http://download.csdn.net/source/1408924 

如果只是要单独下载电子书的话,请看这里:

 http://download.csdn.net/source/1408940

注意:开发环境为VS2008SP1,而其是控制台程序,没有输出,想看时如何测试各个函数的,请自行断点跟踪,程序是我测试过的,不存在错误,除非您该我代码。当然,您得在PLC的地址中开放必要的地址以供测试。

 

posted @ 2009-06-16 08:45  臭臭的大佬  阅读(4938)  评论(10编辑  收藏  举报