Convert Vb6 to C#

P

Peter

Does anyone know how to convert the following VB6 code to C# code?

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As
Any, Source As Any, ByVal bytes As Long)

Dim sngArray(0) As Single
strString = Chr$(107) & Chr$(62) & Chr(139) & Chr$(65)
CopyMemory sngArray(0), ByVal strString, Len(strString)

After running the code sngArray(0) = 17.40548


Thank You


Peter
 
J

Ji Zhou [MSFT]

Hello Peter,

Thanks for using Microsoft Newsgroup Support Service, my name is Ji Zhou
[MSFT] and I will be working on this issue with you.

Firstly, I want to confirm that I understand your question correctly. We
are trying to get a System.Single type value by combining four unsigned
char's bit value. If my understanding is incorrect, please feel free to let
me know.

I have found two solutions for this objective in C#:

1.Use the Windows API RtlMoveMemory as you did in VB6. But in this
approach, we need to put our codes in unsafe block to use the pointer. My
codes look like:

class Program
{
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError =
false)]
unsafe static extern void CopyMemory(void* dest, void* src, int size);

static void Main(string[] args)
{
unsafe
{
byte[] byteArray = new byte[] { 107, 62, 139, 65 };
float singleValue = 0f;
float* des = &singleValue;
fixed (byte* src = byteArray)
{
CopyMemory(des, src, 4);
}
Console.WriteLine(singleValue.ToString());
}
}
}

2.Actually, it is not necessary to move memory in this case. Thus a better
way is using the BitConverter class in .NET Framework to convert a byte
array to a single type value. Codes are as follows:

class Program
{
static void Main(string[] args)
{
byte[] s = new byte[] { 107, 62, 139, 65 };
Single test = BitConverter.ToSingle(s, 0);
Console.WriteLine(test.ToString());
}
}

The above two code snippets both give me the value 17.40548. I hope this
will help. Please let me know if you have any future questions or concerns.
I will do my best to help on this.


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://support.microsoft.com/select/default.aspx?target=assistance&ln=en-us.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Best regards,
Ji Zhou
 
P

Peter

"Ji Zhou [MSFT]" said:
Hello Peter,

Thanks for using Microsoft Newsgroup Support Service, my name is Ji Zhou
[MSFT] and I will be working on this issue with you.

Firstly, I want to confirm that I understand your question correctly. We
are trying to get a System.Single type value by combining four unsigned
char's bit value. If my understanding is incorrect, please feel free to
let
me know.

I have found two solutions for this objective in C#:

1.Use the Windows API RtlMoveMemory as you did in VB6. But in this
approach, we need to put our codes in unsafe block to use the pointer. My
codes look like:

class Program
{
[DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory", SetLastError =
false)]
unsafe static extern void CopyMemory(void* dest, void* src, int size);

static void Main(string[] args)
{
unsafe
{
byte[] byteArray = new byte[] { 107, 62, 139, 65 };
float singleValue = 0f;
float* des = &singleValue;
fixed (byte* src = byteArray)
{
CopyMemory(des, src, 4);
}
Console.WriteLine(singleValue.ToString());
}
}
}

2.Actually, it is not necessary to move memory in this case. Thus a better
way is using the BitConverter class in .NET Framework to convert a byte
array to a single type value. Codes are as follows:

class Program
{
static void Main(string[] args)
{
byte[] s = new byte[] { 107, 62, 139, 65 };
Single test = BitConverter.ToSingle(s, 0);
Console.WriteLine(test.ToString());
}
}

The above two code snippets both give me the value 17.40548. I hope this
will help. Please let me know if you have any future questions or
concerns.
I will do my best to help on this.


Best regards,
Ji Zhou ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://support.microsoft.com/select/default.aspx?target=assistance&ln=en-us.
==================================================
This posting is provided "AS IS" with no warranties, and confers no
rights.

Best regards,
Ji Zhou

How come the following does not return the same value as yours and how can I
make it return the same value?

class Program
{
static void Main(string[] args)
{
//byte[] b = new byte[] { 107, 62, 139, 65 };

string s = new string((char)107, 1);
s += new string((char)62, 1);
s += new string((char)139, 1);
s += new string((char)65, 1);

System.Text.ASCIIEncoding ascii = new System.Text.ASCIIEncoding();
byte[] b = ascii.GetBytes(s);
Single test = BitConverter.ToSingle(b, 0);
Console.WriteLine(test.ToString());
}
}
 
P

Peter

Peter Duniho said:
How come the following does not return the same value as yours and how
can I
make it return the same value? [...]

The fundamental answer to that question is that your code is not doing the
same thing, so it returns a different value. The way to make it return
the same value is to fix your code so that it does the same as the
original.

As for why the code you posted doesn't accomplish your goal, the reason
for that is the same as it was when you asked basically the identical
question in the "convert string to byte array" thread. Nothing's changed
since then that would lead to a new answer.

Your most recent post in that thread said that the issue here is that
you're trying to get strings out of a database and convert the binary data
into floats. So it's not clear at all why you want to construct the
string in code anyway; isn't the real problem to take string data from the
database and convert that? How would replicating the data
programmatically help here?

Unfortunately, I don't have the experience with databases to come up with
an answer of how to get raw binary data out of a database when it was put
there as a string. I don't know of any way in .NET to keep your string in
anything other than UTF-16 and still be known as a string, as that's the
type used by the String class. Even if you could stipulate that the data
coming from the database is another encoding, it'd be converted in order
to get it into a String instance, at which point you could lose
information.

It seems to me what you really need is a way to ignore that the database
data is technically a string, and just retrieve it as pure bytes. How to
do that, I'm not sure. But I feel reasonably confident that this messing
around with the character encodings is likely to produce unreliable
results.

Pete

When I read the string from the Access database in VB6.0 I get the following
ASCII values
(the string is 1024 bytes long, but each four bytes is a float so for
simplicity sake let's pretend there are only 4 bytes)
107,62,139,65

but if I read the same data using C# and run the following code,

char[] cs = s.ToCharArray();

the cs contains the following { 107, 62, 8249, 65 } // this is what displays
when I hover the mouse pointer over the cs variable in debug mode.
When I move the mouse pointer over the the string variable it has the same
contents as the one in VB6.0, but when I convert it to byte array the byte
array contains different values - specfically the 3 byte - in VB6 it's 139
but in C# it's 8249.

how can the C# version to have to same values as in VB6.0 version?

Thank You


Peter
 
P

Peter

Peter Duniho said:
[...]
When I read the string from the Access database in VB6.0 I get the
following
ASCII values
(the string is 1024 bytes long, but each four bytes is a float so for
simplicity sake let's pretend there are only 4 bytes)
107,62,139,65

Note: 139 isn't a valid ASCII value. ASCII only goes up to 127. VB6.0 is
supporting an ANSI code page that goes up to 255.
but if I read the same data using C# and run the following code,

char[] cs = s.ToCharArray();

the cs contains the following { 107, 62, 8249, 65 } // this is what
displays
when I hover the mouse pointer over the cs variable in debug mode.

Because in C#, a char is a 16-bit Unicode value, not the ANSI code page.
The 139 has to be converted to a valid Unicode value, and so it is.

As Jon's pointed out, _maybe_ you can get away with then converting this
Unicode values back to the relevant ANSI encoding and get the bytes that
way. But you would certainly (as he suggests) want to run a test pattern
through that includes all 256 bytes values from 0 to 255, and make sure
that they make it through unscathed.

Pete


Thank you

Encoding.GetEncoding(1252) did the trick, now I can convert the memo field
in Access to varbinary(MAX) field in MS SQL.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top