Hi,
While debugging the converted VO application, I found a difference in the way of converting strings between a group of functions like Mem2String, StringAlloc, etc. on the one hand, and Bin2_, _2Bin on the other. As we know, strings in NET are Unicode, and in VO they are ANSI. XSharp (as I saw from the source code in XSharpPublic) uses Windows code page (Encoding (WinCodePage)) string transformations for consistent behavior. But it is used only in the set of functions Mem2String, StringAlloc, etc. And the Bin2_, _2Bin function set uses a different approach - an attempt to store the original byte value in Unicode strings. As a result, it turns out that these functions work correctly within their sets, but not among themselves. And this leads to the inoperability of the VO application, where all these functions were compatible.
At the same time, as I understand it, these functions came from VO and should provide compatibility in a VO application. After all, if we are talking about a NET application, then there is a huge selection of tools for such operations: BitConverter, System.Text.Encoding, Marshal.StringToHGlobalAnsi, etc.
Need some advice on how to work around this issue in XSharp in a converted VO application now. Will there be any changes in Runtime related to these?
Best regards,
Leonid
Problem with packing and unpacking data in Bin2* and *2Bin functions
Problem with packing and unpacking data in Bin2* and *2Bin functions
Best regards,
Leonid
Leonid
Problem with packing and unpacking data in Bin2* and *2Bin functions
Hi Leonid,
There can me changes in the runtime, or you may just simply redefine those functions in your code, making them work exactly as you want them to.
Can you please post a small (but compilable) sample demonstrating the incompatibilities you are getting?
There can me changes in the runtime, or you may just simply redefine those functions in your code, making them work exactly as you want them to.
Can you please post a small (but compilable) sample demonstrating the incompatibilities you are getting?
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
Problem with packing and unpacking data in Bin2* and *2Bin functions
Hi Chris,
The example is very simple:
Result: w equals 0x1040 instead of 0x10F0
Best regards,
Leonid
The example is very simple:
Code: Select all
LOCAL DIM p[2] AS BYTE // In a real application, this data is read, for example, from a file.
p[1] := 0xF0
p[2] := 0x10
LOCAL c AS STRING
c := Mem2String(@p, 2)
LOCAL w AS WORD
w := Bin2W(c)
Best regards,
Leonid
Best regards,
Leonid
Leonid
Problem with packing and unpacking data in Bin2* and *2Bin functions
Hi Leonid,
Thanks! I understand that this is only a sample, but in your real code, do you rely on the first conversion to a string with Mem2String(), do you use this returned string for anything else, apart from using it as an intermediate result, before you convert it again with Bin2W()? If it's not needed for anything else, then I think the best solution is to adjust the code so it simply generates the word directly from the byte pointer values.
If you do need the string for something more, or if this is used in too many places and you do not want to change the existing code, then you can just adjust the Bin2W(), so it works as needed by your code. Please define the following in any of your base libraries, the compiler will now pick this one, instead of the one defined in the X# runtime. Can you please check if it always gives the expected results?
Thanks! I understand that this is only a sample, but in your real code, do you rely on the first conversion to a string with Mem2String(), do you use this returned string for anything else, apart from using it as an intermediate result, before you convert it again with Bin2W()? If it's not needed for anything else, then I think the best solution is to adjust the code so it simply generates the word directly from the byte pointer values.
If you do need the string for something more, or if this is used in too many places and you do not want to change the existing code, then you can just adjust the Bin2W(), so it works as needed by your code. Please define the following in any of your base libraries, the compiler will now pick this one, instead of the one defined in the X# runtime. Can you please check if it always gives the expected results?
Code: Select all
FUNCTION Bin2W(cUnsignedInt AS STRING) AS WORD
LOCAL wResult := 0 AS WORD
IF cUnsignedInt!= NULL .AND. cUnsignedInt:Length >= 2
cUnsignedInt := cUnsignedInt:Substring(0,2)
LOCAL aBytes AS BYTE[]
aBytes := StringHelpers.WinEncoding:GetBytes(cUnsignedInt)
wResult := BitConverter.ToUInt16(aBytes, 0)
ENDIF
RETURN wResult
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu
Problem with packing and unpacking data in Bin2* and *2Bin functions
Chris,
Yes, this string contains a lot of different data packed into a string. In a real application, there is an array (ARRAY), in which different types of data: numbers, texts.
For example:
Using a special function, such an array is packed into a string (STRING) and saved, for example, to a file (in a separate file or in the MEMO field of a DBF file). When reading back, the read data buffer (BYTE PTR) is converted into a string (Mem2String) and parsed into its components - numbers, strings. Numbers are read using Bin2, strings - as is.
After your first answer, I wrote a set of static methods (so as not to interfere with the original functions) that use WinEncoding:
Best regards,
Leonid
Yes, this string contains a lot of different data packed into a string. In a real application, there is an array (ARRAY), in which different types of data: numbers, texts.
For example:
Code: Select all
{
{ 0, "SomeName0" },
{ 1, "SomeName1" },
{ 2, "SomeName2", { Date, Val1, Val2, .... "some text" } },
...
}
After your first answer, I wrote a set of static methods (so as not to interfere with the original functions) that use WinEncoding:
Code: Select all
BEGIN NAMESPACE <MyNamespace>
PUBLIC STATIC CLASS WinEncoding
PUBLIC STATIC METHOD DW2Bin(dwValue AS DWORD) AS STRING
LOCAL byteArray := BitConverter.GetBytes(dwValue) AS BYTE[]
RETURN StringHelpers.WinEncoding:GetString(byteArray)
PUBLIC STATIC METHOD Bin2DW(cUnsignedInt AS STRING) AS DWORD
IF ( cUnsignedInt != NULL .AND. cUnsignedInt:Length >= 4 )
VAR byteArray := BYTE[]{ 4 }
StringHelpers.WinEncoding:GetBytes(cUnsignedInt, 0, 4, byteArray, 0)
RETURN BitConverter.ToUInt32(byteArray, 0)
ENDIF
RETURN 0
... etc ...
END CLASS
END NAMESPACE
Leonid
Best regards,
Leonid
Leonid
Problem with packing and unpacking data in Bin2* and *2Bin functions
Hi Leonid,
OK, sounds good, that's the beauty of it, you can make everything work exactly the way it suits you!
OK, sounds good, that's the beauty of it, you can make everything work exactly the way it suits you!
Chris Pyrgas
XSharp Development Team
chris(at)xsharp.eu
XSharp Development Team
chris(at)xsharp.eu