Cannot convert sbyte to char

9 posts / 0 new
Last post
Offline
Last seen: 7 months 3 weeks ago
Joined: 03/16/2016
Posts: 12
Cannot convert sbyte to char

Hi RTI,

I am migrating from 5.3 to 6.1 RTI DDS Connext. The programming language is C# in my implementation. Other peers could be JAVE, C, C++ etc.

C# has a sbyte primitive type. In 5.3, I used to do this to convert sbyte to char and it has been working for the whole sbyte range -128 to 127

dynamicData.set_char(memberName, memberId, Convert.ToChar((byte)( (sbyte) memberValue) ));

In 6.1, the SetValue method is not happy with the converted char when the sbyte is negative. I get this exception.

System.ArgumentExecption: 'The output byte buffer is too small contain the encoded data, encoding 'Unicode (UTF-8)' fallback 'System.Text.EncoderReplacementFallback'. (Parameter 'bytes')'

I aslo tried to convert the sbyte to a byte array and then convert the array to a UTF8 string and get the first character but I stiil get the same error.

var convertChar = Encoding.UTF8.GetString(new byte[] { (byte) sb }.ToCharArray().First();

Thanks,

Gary 

 

 

 

Organization:
Offline
Last seen: 2 months 2 weeks ago
Joined: 04/02/2013
Posts: 194

The IDL type char is treated as a single UTF-8 character. When you pass a C# char (2 bytes), Connext DDS is trying to convert it to a single 1-byte UTF-8 character.

To store any 8-bit integer, you need an IDL octet instead of an IDL char.

Offline
Last seen: 7 months 3 weeks ago
Joined: 03/16/2016
Posts: 12

I thought about using octet instead but I am concerned other peers will not receive the message correctly. Like I said, it used to work with char in version 5.3. 

Offline
Last seen: 2 months 2 weeks ago
Joined: 04/02/2013
Posts: 194

Unfortunately the old language binding was too permissive in this regard. There's currently no workaround, short of manually editing the generated code. We will consider adding an option to allow the permissive use of char as any integer.

Offline
Last seen: 7 months 3 weeks ago
Joined: 03/16/2016
Posts: 12

I think I will need to wait for this change before I can upgrade to 6.1. Otherwise, the new version will break backward compatibility. 

Offline
Last seen: 2 months 2 weeks ago
Joined: 04/02/2013
Posts: 194

This workaround involves changing some installed files by hand.

You would need to replace:

<install dir>/resource/app/app_support/rtiddsgen_dotnet/templates/cs/typePluginMacros.vm
   318: ${member.name} = NativeChar.ToUtf8(sample.${member.name});

with

           ${member.name} = (byte) (sample.${member.name});

 

And 

<install dir>/resource/app/app_support/rtiddsgen_dotnet/templates/cs/typePluginMacros.vm

      236: sample.${member.name} = NativeChar.FromUtf8(${member.name});

 

With 

        sample.${member.name} = (char) (${member.name});

 

And then regenerate the code for your IDL files.

Offline
Last seen: 7 months 3 weeks ago
Joined: 03/16/2016
Posts: 12

Thank you Alex.

Unforturnately, we are not generating code from IDL. We have our own message schema and code generator, and we convert the C# messages to DynamicData.

Offline
Last seen: 7 months 3 weeks ago
Joined: 03/16/2016
Posts: 12

Oh...I just noticed setting char value greater than 127 does not work either. 

dynamicData.SetValue<char>(memberName, (char) 128);

Offline
Last seen: 7 months 3 weeks ago
Joined: 03/16/2016
Posts: 12

Any idea why SetValue<char> won't take value greater than 127?

Gary