Read/Write string types

ADS Server usually support strings in 2 flavors. The Default (ANSI) and the Unicode encoding (STRING vs. WSTRING) The ANSI encoding reserves 1 byte per character. Unicode reserves 2.

The strings are of fixed size and therefore the length of the the reserved space within the process image is important.

HowTo Read/Write string values

Reading writing ANSI Streams:

Read/Write ANSI Strings (async)

CancellationToken cancel = CancellationToken.None;

using (AdsClient client = new AdsClient())
{
    client.Connect(AmsNetId.Local, 851); // Connect to local port 851 (PLC)

    ResultHandle resultHandle = await client.CreateVariableHandleAsync("MAIN.string",cancel); // Symbol "string" in MAIN defined as string

    if (resultHandle.Succeeded)
    {
        try
        {
            // Read ANSI String string[80]
            int byteSize = 81; // Size of 80 ANSI chars + /0 (STRING[80])
            PrimitiveTypeMarshaler converter = new PrimitiveTypeMarshaler(StringMarshaler.DefaultEncoding);
            byte[] buffer = new byte[byteSize];

            ResultRead resultRead = await client.ReadAsync(resultHandle.Handle, buffer.AsMemory(), cancel);

            if (resultRead.Succeeded)
            {
                string value = null;
                converter.Unmarshal<string>(buffer.AsSpan(), out value);

                byte[] writeBuffer = new byte[byteSize];
                // Write ANSI String string[80]
                value = "Changed";
                converter.Marshal(value, writeBuffer);
                ResultWrite resultWrite = await client.WriteAsync(resultHandle.Handle, writeBuffer, cancel);
            }
        }
        finally
        {
            ResultAds r1 = await client.DeleteVariableHandleAsync(resultHandle.Handle, cancel);
        }
    }
}

Read/Write ANSI Strings (sync)

using (AdsClient client = new AdsClient())
{
    client.Connect(AmsNetId.Local, 851); // Connect to local port 851 (PLC)
    uint handle = client.CreateVariableHandle("MAIN.string"); // Symbol "string" in MAIN defined as string

    try
    {
        // Read ANSI String string[80]
        int byteSize = 81; // Size of 80 ANSI chars + /0 (STRING[80])
        PrimitiveTypeMarshaler converter = new PrimitiveTypeMarshaler(StringMarshaler.DefaultEncoding);
        byte[] buffer = new byte[byteSize];

        int readBytes = client.Read(handle, buffer.AsMemory());

        string value = null;
        converter.Unmarshal<string>(buffer.AsSpan(), out value);

        // Write ANSI String string[80]
        byte[] writeBuffer = new byte[byteSize];
        value = "Changed";
        converter.Marshal(value, writeBuffer);
        client.Write(handle, writeBuffer);
    }
    finally
    {
        client.DeleteVariableHandle(handle);
    }
}

Reading writing UNICODE Streams:

Read/Write Unicode Strings (async)

CancellationToken cancel = CancellationToken.None;

using (AdsClient client = new AdsClient())
{
    client.Connect(AmsNetId.Local, 851); // Connect to local port 851 (PLC)
    ResultHandle resultHandle = await client.CreateVariableHandleAsync("MAIN.wstring",cancel); // Symbol "wstring" defined in MAIN as WSTRING

    if (resultHandle.Succeeded)
    {
        try
        {
            // Read UNICODE String wstring[80]
            PrimitiveTypeMarshaler converter = new PrimitiveTypeMarshaler(Encoding.Unicode);
            int byteSize = converter.MarshalSize(80); // Size of 80 UNICODE chars + /0 (WSTRING[80]) (162)
            byte[] readBuffer = new byte[byteSize];

            ResultRead resultRead = await client.ReadAsync(resultHandle.Handle, readBuffer, cancel);

            if (resultRead.Succeeded)
            {
                string value = null;
                converter.Unmarshal(readBuffer.AsSpan(), out value);

                // Write Unicode String string[80]
                value = "Changed";
                byte[] writeBuffer = new byte[byteSize];
                converter.Marshal(value, writeBuffer.AsSpan());

                ResultWrite resultWrite = await client.WriteAsync(resultHandle.Handle, writeBuffer.AsMemory(), cancel);
            }
        }
        finally
        {
            ResultAds r1 = await client.DeleteVariableHandleAsync(resultHandle.Handle, cancel);
        }
    }
}

Read/Write Unicode Strings (sync)

using (AdsClient client = new AdsClient())
{
    client.Connect(AmsNetId.Local, 851); // Connect to local port 851 (PLC)
    uint handle = client.CreateVariableHandle("MAIN.wstring"); // Symbol "wstring" defined in MAIN as WSTRING

    try
    {
        // Read UNICODE String wstring[80]

        PrimitiveTypeMarshaler converter = new PrimitiveTypeMarshaler(Encoding.Unicode);
        int byteSize = converter.MarshalSize(80); // Size of 80 UNICODE chars + /0 (WSTRING[80]) (162)
        byte[] readBuffer = new byte[byteSize];

        int readBytes = client.Read(handle, readBuffer);

        string value = null;
        converter.Unmarshal(readBuffer.AsSpan(), out value);

        // Write Unicode String string[80]
        value = "Changed";
        byte[] writeBuffer = new byte[byteSize];
        converter.Marshal(value, writeBuffer.AsSpan());

        client.Write(handle, writeBuffer.AsMemory());
    }
    finally
    {
        client.DeleteVariableHandle(handle);
    }
}

Reading writing strings with ReadAny/WriteAny group of methods:

Read/Write Anystring (async)

CancellationToken cancel = CancellationToken.None;

using (AdsClient client = new AdsClient())
{
    client.Connect(AmsNetId.Local, 851); // Connect to local port 851 (PLC)

    ResultHandle resultHandleStr = await client.CreateVariableHandleAsync("MAIN.string",cancel); // Symbol "string" defined in MAIN as STRING
    ResultHandle resultHandleWStr = await client.CreateVariableHandleAsync("MAIN.wstring",cancel); // Symbol "string" defined in MAIN as WSTRING

    if (resultHandleStr.Succeeded && resultHandleWStr.Succeeded)
    {
        try
        {
            ResultAnyValue resultReadStr = await client.ReadAnyStringAsync(resultHandleStr.Handle, 80, StringMarshaler.DefaultEncoding, cancel);
            ResultAnyValue resultReadWStr = await client.ReadAnyStringAsync(resultHandleWStr.Handle, 80, Encoding.Unicode, cancel);

            string changedValue = "Changed";

            // Attention, take care that the memory of the string in the process image is not exceeded!
            ResultWrite resultWriteStr = await client.WriteAnyStringAsync(resultHandleStr.Handle, changedValue, 80, StringMarshaler.DefaultEncoding, cancel);
            ResultWrite resultWriteWStr = await client.WriteAnyStringAsync(resultHandleWStr.Handle, changedValue, 80, Encoding.Unicode, cancel);
        }
        finally
        {
            ResultAds r1 = await client.DeleteVariableHandleAsync(resultHandleStr.Handle, cancel);
            ResultAds r2 = await client.DeleteVariableHandleAsync(resultHandleWStr.Handle, cancel);
        }
    }
}

Read/Write Anystring (sync)

using (AdsClient client = new AdsClient())
{
    client.Connect(AmsNetId.Local, 851); // Connect to local port 851 (PLC)

    uint stringHandle = client.CreateVariableHandle("MAIN.string"); // Symbol "string" defined in MAIN as STRING
    uint wStringHandle = client.CreateVariableHandle("MAIN.wstring"); // Symbol "string" defined in MAIN as WSTRING

    try
    {
        string str = client.ReadAnyString(stringHandle, 80, StringMarshaler.DefaultEncoding);
        string wStr = client.ReadAnyString(wStringHandle, 80, Encoding.Unicode);

        string changedValue = "Changed";

        // Attention, take care that the memory of the string in the process image is not exceeded!
        client.WriteAnyString(stringHandle, changedValue, 80, StringMarshaler.DefaultEncoding);
        client.WriteAnyString(wStringHandle, changedValue, 80, Encoding.Unicode);
    }
    finally
    {
        client.DeleteVariableHandle(stringHandle);
        client.DeleteVariableHandle(wStringHandle);
    }
}

Beckhoff Automation GmbH & Co. KG 2001-2026