Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Reading flatten string from Network Variable

We have some RT targets writing cluster data to a Network Variable on a Windows machine. The variable type is string. Data is written using "Flatten To String". Everything worked fine when reading the variable and unflatten the value in Labview.

 

Now, we tried the read task from Measurement Studio .NET. Unfortunately, the NetworkVariableReader always returns an empty string. I'm afraid that marshalling the "binary ANSI string" is not supported. I can't find any limitations for strings in the Measurement Studio docs. Furthermore, passing a flatten string through a Labview .NET Interop Assembly works in both ways.

 

Final question: How do I read a flatten string from a Network Variable in .NET? Refactoring RT code is not possible.

0 Kudos
Message 1 of 7
(3,120 Views)

I will try to break down the problem to a minimum.

See the following example:

write_network_variable_string.pngSteps:

  • Flatten an i32-value to string
  • Write that string to a network variable
  • Read that string from that network variable
  • Get the string's length

As expected, the result is always 4.

 

Now, I will read the string in C# and get its length.

 

int GetLength()
{
    using (var reader = new NetworkVariableReader<string>(@"\\localhost\foo_process\string_var"))
    {
        reader.Connect();
        string value = reader.ReadData().GetValue();
        return value.Length;
    }
}

The result is always 0. The string is empty.

 

 

I'm referencing:

NationalInstruments.Common, Version=15.0.40.49154

NationalInstruments.NetworkVariable, Version=15.0.40.49153

 

Thanks for any help!

0 Kudos
Message 2 of 7
(3,073 Views)

It seems that Measurement Studio treats the zero character '\0' as string delimiter. Therefore, all characters in a .NET string behind a zero character are ignored.

 

  • The zero char is a regular char in a .NET string.
  • Why behaves Measurement Studio different than Labview?
  • Why is that behavior not documented?

Thanks!

0 Kudos
Message 3 of 7
(3,056 Views)

Assuming this .NET app is running on a windows PC, try changing the byte order to little-endian on the flatten to string VI.

 

Hope this helps!

Trent

https://www.linkedin.com/in/trentweaver
0 Kudos
Message 4 of 7
(3,028 Views)

Hi Trent,

 

changing the byte order results in different error cases only. As long as the binary representation contains a zero-byte, the string in the network variable is truncated. This is not a problem of "flatten to string". The VI was the reason I stumbled upon.

 

Please, have a look at the following unit test: 

 

[TestCase("Bar")]
[TestCase("Foo\0Bar")]
[TestCase("\u0001\u0002\u0003\u0004")]
[TestCase("\u0001\u0002\0\u0004")]
public void WriteReadStringNetworkVariable(string value)
{
    const string varLocation = @"\\localhost\foo_process\string_var";

    using (var writer = new NetworkVariableWriter<string>(varLocation))
    {
        writer.Connect();
        writer.WriteValue(value);
    }

    string valueRead;
    using (var reader = new NetworkVariableReader<string>(varLocation))
    {
        reader.Connect();
        valueRead = reader.ReadData().GetValue();
    }
            
    Assert.That(valueRead, Is.EqualTo(value));
}

 

This test writes a string to a network variable, reads that string and asserts equality. Consistently, the test cases containing a zero char fail: 

 

Expected: "Foo\0Bar"
But was:  "Foo"

Expected: "\u0001\u0002\0\u0004"
But was:  "\u0001\u0002"

 

It seems that Measurement Studio .NET treats '\0' as string terminator, like in a good old C-string.

 

 

0 Kudos
Message 5 of 7
(3,024 Views)

I believe it's actually the shared variable engine, where the variable is hosted, that is storing this as a C string. Looking at the data type in NI Distributed System Manager supports this:

Capture.PNG

Since System.String is a Microsoft class and isn't going to match the LabVIEW string type, you could probably get around this following these instructions from the help:

Complex types may be written using .NET serialization, but are only supported when communicating from one instance of .NET to another instance of .NET. LabVIEW and LabWindows/CVI do not have a way of understanding complex types, such as classes. To write a complex type to a network variable, serialize the object into a byte[] and then write the byte[] to the network variable. To read a complex type from a network variable, read the byte[] and deserialize it back to the Object.

I'll file a CAR to see if we can make this more clear in the documentation.

 

Hope this helps!

Trent

https://www.linkedin.com/in/trentweaver
0 Kudos
Message 6 of 7
(3,002 Views)

.NET's System.String is not a complex type and explicitly meant to be supported by the Network Variable classes in Measurement Studio .NET, as documented here or here. I know that byte arrays would be the better choice, but Labview developers are forced to treat binary data as strings, see the flatten/unflatten or TCP VIs. As a consequence, we have binary strings stored in the SVE. A circumstance that can't be changed currently.

 

From my understanding, the SVE process (running on Windows in this case) can't be the reason for the null-termination issue. Regardless of how the SVE stores a string value, Labview Windows and Labview RT are able to read and write strings with NUL characters from and to the SVE. See my first post. The affected strings have to go into the SVE and out of the SVE, somehow. The incorrect handling of string values affects Measurement Studio .NET only. I assume that this happens in the native library under the hood of NationalInstruments.NetworkVariable.dll.

 

By the way, the term ANSI String is confusing me. In the context of Labview I always thought it refers to the Windows-1252 character encoding. Nevertheless, the encoding has nothing to do with string termination. It even defines 0x00 as the valid 'NUL' character.

 

Thanks for your help,

Jonas

0 Kudos
Message 7 of 7
(2,967 Views)