通过 C# 应用程序使用 TwinCAT.Ads 写入结构数组
Write array of struct using TwinCAT.Ads through C# application
我正在使用 TwinCAT.Ads (TwinCAT 3) 通过 C# 应用程序与 Beckhoff plc 通信。应用程序正在读取和写入几个 plc 变量。我收到一个错误:
“Unable to marshal object. Parameter name: value”
写结构变量数组时。但是应用程序正在读取它而没有任何错误。
任何帮助将不胜感激。下面是我的代码示例。
Plc 中的结构
TYPE Station :
STRUCT
ClusterID : STRING[10];
Tech_Type : USINT;
Status : BOOL;
Reject : BOOL;
Rej_Detail : STRING[50];
Rej_Catagory : USINT;
END_STRUCT
END_TYPE
Class 在 c#
中
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class Station
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string ClusterID;
public byte Tech_Type;
[MarshalAs(UnmanagedType.I1)]
public bool Status;
[MarshalAs(UnmanagedType.I1)]
public bool Reject;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
public string Rej_Detail;
public byte Rej_Catagory;
}
我正在编写以下代码,其中 handles[0] 是变量句柄,stations 是 class 的数组长度为 5.
adsClient.WriteAny(handles[0], stations, new int[] { 5 });
我猜你错过了 PLC 中的对应项。请确保在您的 PLC 中声明了一组站,例如:
// I have it in a global variable list named: STG_Variables
stat_array_Var : array [0..5] of Station;
这段 C# 代码适合我:
TcAdsClient AdsComClient = new TcAdsClient();
AdsComClient.Connect(NetID_TwinCat, 851);
int handle_array = AdsComClient.CreateVariableHandle("STG_Variables.stat_array_Var");
// get some test stations:
Station station = new Station();
Station station2 = new Station();
Station station3 = new Station();
Station station4 = new Station();
Station station5 = new Station();
Station[] station_plural = new Station[] { station, station2, station3, station4, station5 };
// write some stuff to recognize that write test worked
for (int i = 0; i < station_plural.Length; i++)
{
station_plural[i].ClusterID = "ID: " + i.ToString();
}
// just use the normal WriteAny method without the new int[] { 5 } parameter!
// send it down to the plc
AdsComClient.WriteAny(handle_array, plural);
我不知道你的句柄handles[0]
指向哪里。写一个 Station
的数组不应该在 plc 的一个单一结构中结束。试试我的版本,请评论它是否适合你。
编辑:我在 C# 中使用了这个 class 定义:
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class Station
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string ClusterID;
public byte Tech_Type;
[MarshalAs(UnmanagedType.I1)]
public bool Status;
[MarshalAs(UnmanagedType.I1)]
public bool Reject;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
public string Rej_Detail;
public byte Rej_Catagory;
}
并创建了一个 DUT
并在 PLC 中使用了这个结构定义:
TYPE Station :
STRUCT
ClusterID : STRING[10];
Tech_Type : USINT;
Status : BOOL;
Reject : BOOL;
Rej_Detail : STRING[50];
Rej_Catagory : USINT;
END_STRUCT
END_TYPE
并声明了Station
s的数组变量,如上所述。
并且有效。我能够将结构写到 PLC 中,并在数组
中看到 "ID: 0"
、 "ID: 1"
、 "ID: 2"
等字符串
我正在使用 TwinCAT.Ads (TwinCAT 3) 通过 C# 应用程序与 Beckhoff plc 通信。应用程序正在读取和写入几个 plc 变量。我收到一个错误:
“Unable to marshal object. Parameter name: value”
写结构变量数组时。但是应用程序正在读取它而没有任何错误。 任何帮助将不胜感激。下面是我的代码示例。
Plc 中的结构
TYPE Station :
STRUCT
ClusterID : STRING[10];
Tech_Type : USINT;
Status : BOOL;
Reject : BOOL;
Rej_Detail : STRING[50];
Rej_Catagory : USINT;
END_STRUCT
END_TYPE
Class 在 c#
中[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class Station
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string ClusterID;
public byte Tech_Type;
[MarshalAs(UnmanagedType.I1)]
public bool Status;
[MarshalAs(UnmanagedType.I1)]
public bool Reject;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
public string Rej_Detail;
public byte Rej_Catagory;
}
我正在编写以下代码,其中 handles[0] 是变量句柄,stations 是 class 的数组长度为 5.
adsClient.WriteAny(handles[0], stations, new int[] { 5 });
我猜你错过了 PLC 中的对应项。请确保在您的 PLC 中声明了一组站,例如:
// I have it in a global variable list named: STG_Variables
stat_array_Var : array [0..5] of Station;
这段 C# 代码适合我:
TcAdsClient AdsComClient = new TcAdsClient();
AdsComClient.Connect(NetID_TwinCat, 851);
int handle_array = AdsComClient.CreateVariableHandle("STG_Variables.stat_array_Var");
// get some test stations:
Station station = new Station();
Station station2 = new Station();
Station station3 = new Station();
Station station4 = new Station();
Station station5 = new Station();
Station[] station_plural = new Station[] { station, station2, station3, station4, station5 };
// write some stuff to recognize that write test worked
for (int i = 0; i < station_plural.Length; i++)
{
station_plural[i].ClusterID = "ID: " + i.ToString();
}
// just use the normal WriteAny method without the new int[] { 5 } parameter!
// send it down to the plc
AdsComClient.WriteAny(handle_array, plural);
我不知道你的句柄handles[0]
指向哪里。写一个 Station
的数组不应该在 plc 的一个单一结构中结束。试试我的版本,请评论它是否适合你。
编辑:我在 C# 中使用了这个 class 定义:
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class Station
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string ClusterID;
public byte Tech_Type;
[MarshalAs(UnmanagedType.I1)]
public bool Status;
[MarshalAs(UnmanagedType.I1)]
public bool Reject;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 51)]
public string Rej_Detail;
public byte Rej_Catagory;
}
并创建了一个 DUT
并在 PLC 中使用了这个结构定义:
TYPE Station :
STRUCT
ClusterID : STRING[10];
Tech_Type : USINT;
Status : BOOL;
Reject : BOOL;
Rej_Detail : STRING[50];
Rej_Catagory : USINT;
END_STRUCT
END_TYPE
并声明了Station
s的数组变量,如上所述。
并且有效。我能够将结构写到 PLC 中,并在数组
中看到"ID: 0"
、 "ID: 1"
、 "ID: 2"
等字符串