TwinCAT3 - 实现自己的Dictionary
1,前言
C#有字典,TwinCAT没字典,咋办,自己写一个咯
2,C#的字典
C#的字典使用很简单,下面是最基本的使用
Dictionary<string, object> dic = new Dictionary<string, object>();
dic.Add("key1", 1);
dic.Add("key2", "ABC");
dic["key1"] = 2;
var temp = dic["key1"];
dic.Remove("key1");
dic.Clear();
3,TwinCAT3的字典
就先实现第2节展示的几个基本功能吧。
定义功能块
- FB_Dictionary:对应Dictionary<string, object>
FUNCTION_BLOCK FB_Dictionary
VAR_INPUT
END_VAR
VAR_OUTPUT
END_VAR
VAR
// 键数组
keyArr : ARRAY[0..999] OF STRING;
// 值数组
dataArr : ARRAY[0..999] OF STRING(255);
// 值长度数组
lengthArr : ARRAY[0..999] OF UINT;
// 数组序号
ArrayIndex : INT;
END_VAR
本质上就是数组,C#的object就是一块内存,dataArr的每个元素是STRING(255),相当于一块长度为256byte的内存,lengthArr用来表示这块256byte的内存实际用了多少byte。
添加方法
- M_AddOrUpdate:对应Add和写入操作符[]
- M_Get:对应读取操作符[]
- M_Remove:对应Remove
- M_Clear:对应Clear
METHOD M_AddOrUpdate : BOOL
VAR_INPUT
key: STRING; //键
pData: PVOID; //值地址
DataLength: UINT; //值长度
END_VAR
VAR
i : INT;
tempstr : STRING(255); // 值
END_VAR
// 代码部分-----
IF ArrayIndex >= 999 THEN //防越界
RETURN;
END_IF
MEMCPY(ADR(tempstr), pData, MIN(DataLength, 255));
FOR i := 0 TO ArrayIndex - 1 BY 1 DO //相同的键
IF keyArr[i] = key THEN
dataArr[i] := tempstr;
lengthArr[i] := DataLength;
RETURN;
ELSIF LEN(keyArr[i]) <= 0 THEN
keyArr[i] := key;
dataArr[i] := tempstr;
lengthArr[i] := DataLength;
RETURN;
END_IF
END_FOR
keyArr[ArrayIndex] := key;
dataArr[ArrayIndex] := tempstr;
lengthArr[i] := DataLength;
ArrayIndex := ArrayIndex + 1; // 地址+1
METHOD M_Get : BOOL
VAR_INPUT
key: STRING; //键
pData: PVOID; //值地址
END_VAR
VAR
i: INT;
END_VAR
// 代码部分-----
IF ArrayIndex > 0 AND LEN(key) >= 1 THEN
// 遍历查找键值
FOR i := 0 TO ArrayIndex - 1 BY 1 DO
IF keyArr[i] = key THEN
MEMCPY(pData, ADR(dataArr[i]), lengthArr[i]);
M_Get:= TRUE;
RETURN;
END_IF
END_FOR
END_IF
METHOD M_Remove : BOOL
VAR_INPUT
key: STRING; //键
END_VAR
VAR
i : INT;
END_VAR
// 代码部分-----
FOR i := 0 TO ArrayIndex - 1 BY 1 DO //相同的键
IF keyArr[i] = key THEN
keyArr[i] := '';
dataArr[i] := '';
lengthArr[i] := 0;
M_Remove:= TRUE;
RETURN;
END_IF
END_FOR
METHOD M_Clear : BOOL
VAR_INPUT
END_VAR
// 代码部分-----
// 字典重置
ArrayIndex := 0;
MEMSET(ADR(keyArr), 0, SIZEOF(keyArr));
MEMSET(ADR(dataArr), 0, SIZEOF(dataArr));
MEMSET(ADR(lengthArr), 0, SIZEOF(lengthArr));
4,用起来
PROGRAM MAIN
VAR
A1: INT;
Dictionary: FB_Dictionary;
TempBool: BOOL;
key1 : STRING := 'int';
value1 : INT := 100;
value1_ : INT;
key2 : STRING := 'real';
value2 : REAL := 1.5;
value2_ : REAL;
key3 : STRING := 'string';
value3 : STRING := 'xxxx';
value3_ : STRING;
END_VAR
// 代码部分-----
//NICE!!
CASE A1 OF
0:
Dictionary.M_AddOrUpdate(key:= key1, pData:= ADR(value1), DataLength:= SIZEOF(value1));
Dictionary.M_AddOrUpdate(key:= key2, pData:= ADR(value2), DataLength:= SIZEOF(value2));
Dictionary.M_AddOrUpdate(key:= key3, pData:= ADR(value3), DataLength:= SIZEOF(value3));
1:
TempBool:= Dictionary.M_Get(key:= key1, pData:= ADR(value1_));
TempBool:= Dictionary.M_Get(key:= key2, pData:= ADR(value2_));
TempBool:= Dictionary.M_Get(key:= key3, pData:= ADR(value3_));
2:
TempBool:= Dictionary.M_Remove(key:= key1);
TempBool:= Dictionary.M_Remove(key:= key2);
3:
Dictionary.M_Clear();
END_CASE