Beckhoff C# Reading array of string from PLC

5.3k views Asked by At

I want to ask about reading string array from PLC Beckhoff.

I have some methods for reading Int16 - it works correctly

public Int16[] ReadArrFromPLC_Int16(string Mnemonic, int ArrLength)
{
    Int16[] TempVariable = null;

    try
    {
        ITcAdsSymbol itc = PLC3.adsClient.ReadSymbolInfo(Mnemonic);
        long indexGroup = itc.IndexGroup; ;
        long indexOffset = itc.IndexOffset;

        int[] args = { ArrLength }; 
        TempVariable = (Int16[])PLC3.adsClient.ReadAny(indexGroup, indexOffset, typeof(Int16[]) , args);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, Mnemonic);
    }
    return TempVariable;
}

but if I want to read array of string I get some exception: "Unable to marshal type. Parameter Name: type" in bold place: ...adsClient.ReadAny(indexGroup, indexOffset, typeof(string[]), args);

public string[] ReadArrFromPLC_String(string Mnemonic, int ArrLength)
{
    string[] TempVariable = null;

    try
    {
        ITcAdsSymbol itc = PLC3.adsClient.ReadSymbolInfo(Mnemonic);
        long indexGroup = itc.IndexGroup; ;
        long indexOffset = itc.IndexOffset;

        int[] args = { ArrLength };
        TempVariable = (string[])PLC3.adsClient.ReadAny(indexGroup, indexOffset, typeof(string[]), args);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, Mnemonic);
    }
    return TempVariable;
}

I can read the array in loop but it take long time.

I found similar topic: MarshalAsAttribute array of strings but I don't know does it help me? and I don't know how I can use it in my case.

1

There are 1 answers

0
Jarek On BEST ANSWER

Thank you Hans Passant for the tip.

Below I show method - it works correctly, but I had to use loop in order to rewrite text from struct to string[].

Is could be something to add?

    [StructLayout(LayoutKind.Sequential)]
    public struct MyString
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 21)] 
        //SizeConst = 21 because in my PLC I declared 
        //"prg : ARRAY[0..200] OF STRING[20];" 
        //(0 to 20 = 21 characters)
        public string Str;
    }
    public string[] ReadArrFromPLC_String(string Mnemonic, int ArrLength)
    {
        MyString[] StrArrFromPLC = null;
        try
        {
            ITcAdsSymbol itc = PLC3.adsClient.ReadSymbolInfo(Mnemonic);
            long indexGroup = itc.IndexGroup; ;
            long indexOffset = itc.IndexOffset;
            int[] args = { ArrLength };
            StrArrFromPLC = (MyString[])PLC3.adsClient.ReadAny(indexGroup, indexOffset, typeof(MyString[]), args);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, Mnemonic);
        }
        string[] TempVariable = new string[StrArrFromPLC.Length];

        for(int i = 0; i < StrArrFromPLC.Length; i++)
        {
            TempVariable[i] = StrArrFromPLC[i].Str;
        }
        return TempVariable;
    }