類似這樣的布局,再加上類似[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]的聲明。
但是,最終單純 的使用2個數組作為“共用體”字段的話是可以通過編譯的,但是再加上unsigned char Mpi的話,OK你是過不了編譯的,就算過了 運行也出錯。反復嘗試還是失敗,最後我聯想到在內存中實際上這個共用體用的是一個以最大字段為空間大小的內存,於是乎嘗試了,直接定 義[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]byteMac[6],果然解決了,共用體的問題,其實C++傳進去的參數也其實是6字節 的數組而已,進而想既然一個數組搞定,那麼還用共用體干嘛,不要了,於是出現了如下函數轉換的正解:
public struct CON_TABLE_TYPE//待連接plc地址屬性表
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
//public CON_ADR_TYPE Adr; // connection address
public byte[] Adr; // connection address
// MPI/PB station address (2)
// IP address (192.168.0.1)
// Mac address (08-00-06-01-AA-BB)
public byte AdrType; // Type of address: MPI/PB (1), IP (2), Mac (3)
public byte SlotNr; // Slot number
public byte RackNr; // Rack number
}
[DllImport ("Prodave6.dll")]//連接PLC操作
//參數:連接號(0-63)、常值"S7ONLINE"、待連接plc地址 屬性表長度(字節為單位,常值9)、待連接plc地址屬性表
public extern static int LoadConnection_ex6(int ConNr, string pAccessPoint, int ConTableLen, ref CON_TABLE_TYPE pConTable);
(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,
}