2

使用 TwinCAT 3 ADS.Net 从 PLC 读取,我试图读取包含结构数组的结构,但 ReadAny 命令因“无法编组类型”异常而崩溃。

不过,直接读取结构数组可以正常工作。

public object ReadAny(long indexGroup, long indexOffset, Type type, int[] args);

ReadAny 方法的头部注释说:“如果要读取的对象的 Type 是数组类型,则必须在参数 args 中指定每个维度的元素数。”

但是对于包含结构数组的结构,args 应该是什么?(没有 'args' 它也会失败。)

我目前使用 .NET 4.7、VS 2013。

有选择吗?

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class WholeData
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    public Station[] StationArray;
    // Potentially more fields...
}

[StructLayout(LayoutKind.Sequential, Pack = 0)]
public class Station
{
    [MarshalAs(UnmanagedType.I1)]
    public bool isPass;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 81)]
    public string name;
    // More fields...
}

// -- Main --
int[] args = { 5 };

// Works fine:
Station[] stationArray = (Station[])m_AdsClient.ReadAny(indexGroup, indexOffset, typeof(Station[]), args);

// Fail:
WholeData wholeData = (WholeData)m_AdsClient.ReadAny(indexGroup, indexOffset, typeof(WholeData), args);
// - OR -
WholeData wholeData = (WholeData)m_AdsClient.ReadAny(m_VarHandle, typeof(WholeData), args);
4

1 回答 1

2

我成功测试了以下代码:

c#代码:

    class Program
    {
        public static TcAdsClient client;
        static void Main(string[] args)
        {


            // Create the ADS Client
            using (client = new TcAdsClient())
            {
                // Establish Connection
                client.Connect(new AmsAddress("10.1.2.95.1.1", 851));
                int handle = client.CreateVariableHandle("PRG_AIS.stAds");

                AdsClass ads = (AdsClass)client.ReadAny(handle, typeof(AdsClass));
                ads.boolArr[0] = 1;
                client.WriteAny(handle, ads);
                Console.ReadLine();

            }
        }
    }

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    class AdsClass
    {

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        public byte[] boolArr = new byte[10];
    }

ST代码:

TYPE AdsStruct :
STRUCT
    bTestArray : ARRAY[0..9] OF BOOL;
END_STRUCT
END_TYPE

AdsStruct 被定义为 PRG_AIS 中的 stAds。

或者,如果您有一个结构数组,请按以下方式修改代码:

c#代码:

[StructLayout(LayoutKind.Sequential, Pack = 1)]
class AdsClass
{

    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
    public InnerStruct[] strArr = new InnerStruct[10];
}

struct InnerStruct
{
    public byte bBoolTest;
    public int nIntTest;
}

ST代码:

TYPE AdsStruct  :
STRUCT
    stTestArray : ARRAY[0..9] OF InnerStruct;
END_STRUCT
END_TYPE

TYPE InnerStruct :
STRUCT
    bBoolTest : BOOL;
    nIntTest  : DINT;
END_STRUCT
END_TYPE
于 2019-07-30T14:09:58.863 回答