469,625 Members | 1,741 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,625 developers. It's quick & easy.

memcpy char* in C#

I have some c++ code that I am converting to C#. What I need to convert is
the following:

memcpy(&tmpshort, (pTmpDataIn+1), 2);

This should copy two bytes of an char* to an int which then gets used
elsewhere. I am having trouble coming up with how to approach.

Thanks,

~ Steve
Dec 27 '07 #1
11 3803
On Thu, 27 Dec 2007 11:45:00 -0800, DatelMonkey99
<da*********@newsgroups.nospamwrote:
I have some c++ code that I am converting to C#. What I need to convert
is
the following:

memcpy(&tmpshort, (pTmpDataIn+1), 2);

This should copy two bytes of an char* to an int which then gets used
elsewhere. I am having trouble coming up with how to approach.
To an int? Or a short?

Maybe something like this:

short tmpshort = BitConverter.ToInt16(pTmpDataIn, 1);

where "pTmpDataIn" is type "byte[]".

Note that in C#, a character array isn't the same as a byte array. If you
don't already have something that is an actual array of bytes or from
which you can get an actual array of bytes, you'll need to be more
specific about your question.

Pete
Dec 27 '07 #2
DatelMonkey99 wrote:
I have some c++ code that I am converting to C#. What I need to convert is
the following:

memcpy(&tmpshort, (pTmpDataIn+1), 2);

This should copy two bytes of an char* to an int which then gets used
elsewhere. I am having trouble coming up with how to approach.
I am not even sure that I understand why memcpy was used in C.

tmpshort = (short)((pTmpDataIn[2] << 8) | pTmpDataIn[1]);

Arne
Dec 28 '07 #3
Hi Steve,

This will depend on how you're converting the "char *" from C to C#: if you
are using a String, then you can get a char array using string.ToCharArray
and add up two chars yourself, just remember a char in C# is a unicode. In
this case, the unmanaged memory will be marshalled to managed string
automatically if you are using P/Invoke function calls and do it correctly.

If you are using an IntPtr in C# to access the unmanaged memory, then you
can use Marshal.ReadInt16, Marshal.ReadInt32, etc. to read the unmanaged
memory.

Hope this helps.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Dec 28 '07 #4
Thank you all for the responses, sorry for not being more clear in my
question.

I am doing some socket programming where I listen on a port then reconstruct
some data from the message. Here is what I am doing in C#.

//Get the message from the socket
int iRx = socketData.m_currentSocket.EndReceive(asyn);

//convert to char[]
char[] chars = new char[iRx + 1];

// Extract the characters as a buffer
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(socketData.dataBuffer, 0, iRx, chars, 0);

This works to a point. However some pieces are not matching that I see in
the c++ source.

The c++ source has some enums setup that give message state. On receive it
first determines the message type & then gets the data from the message.
Here is that code in c++.

//Get message type (SessionMessageId is the enum / pMessageIn in the
unsigned char *)
msgID = (SessionMessageId)*pMessageIn;

//Copy the next two bytes to get the size of the message
memcpy(&tmpshort, (pTmpDataIn+1), 2);
length = ntohs(tmpshort);

I've worked through the posts from Peter & Arne but am still not being able
to get the correct data out of the message.

Thanks,

~ Stev

""Walter Wang [MSFT]"" wrote:
Hi Steve,

This will depend on how you're converting the "char *" from C to C#: if you
are using a String, then you can get a char array using string.ToCharArray
and add up two chars yourself, just remember a char in C# is a unicode. In
this case, the unmanaged memory will be marshalled to managed string
automatically if you are using P/Invoke function calls and do it correctly.

If you are using an IntPtr in C# to access the unmanaged memory, then you
can use Marshal.ReadInt16, Marshal.ReadInt32, etc. to read the unmanaged
memory.

Hope this helps.
Regards,
Walter Wang (wa****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

Dec 28 '07 #5
DatelMonkey99 wrote:
I am doing some socket programming where I listen on a port then reconstruct
some data from the message.

Have you looked at the System.IO.BinaryReader class ?

If your C++ app send in little endian then it should
be very easy to read the data with a BinaryReader !

Arne
Dec 28 '07 #6
On Fri, 28 Dec 2007 05:55:00 -0800, DatelMonkey99
<da*********@newsgroups.nospamwrote:
[...]
The c++ source has some enums setup that give message state. On receive
it
first determines the message type & then gets the data from the message.
Here is that code in c++.

//Get message type (SessionMessageId is the enum / pMessageIn in the
unsigned char *)
msgID = (SessionMessageId)*pMessageIn;

//Copy the next two bytes to get the size of the message
memcpy(&tmpshort, (pTmpDataIn+1), 2);
length = ntohs(tmpshort);
What C# code have you tried?

It's worth noting that while you can use the Encoder class to convert
bytes sent to characters, those characters are not going to be useful
later for getting non-character data, such as the length. You'll need to
use the receive buffer (socketData.dataBuffer) directly with the
BitConverter.

Whether this is the issue you're having trouble with, I don't know. You
need to post code for us to know what you're trying and offer advice as to
how to do it better.

Pete
Dec 28 '07 #7

"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:47***********************@news.sunsite.dk...
DatelMonkey99 wrote:
>I have some c++ code that I am converting to C#. What I need to convert
is the following:

memcpy(&tmpshort, (pTmpDataIn+1), 2); This should copy two bytes of an
char* to an int which then gets used elsewhere. I am having trouble
coming up with how to approach.

I am not even sure that I understand why memcpy was used in C.

tmpshort = (short)((pTmpDataIn[2] << 8) | pTmpDataIn[1]);
There's a potential endianness difference here. memcpy is guaranteed to
work with the local processor endianness in the buffer, while yours is
guaranteed to need LSB-first. Also you need some unsigned casts in that
expression to prevent sign-extension of the LSB from overwriting the MSB.
>
Arne

Dec 31 '07 #8
On Mon, 31 Dec 2007 12:19:53 -0800, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
>I am not even sure that I understand why memcpy was used in C.

tmpshort = (short)((pTmpDataIn[2] << 8) | pTmpDataIn[1]);

There's a potential endianness difference here. memcpy is guaranteed to
work with the local processor endianness in the buffer,
Assuming the data was originally the same endianness as that being used.
That wouldn't be guaranteed if, for example, the data was previously
stored in a file or transmitted over a network or...

So let's assume that we can guarantee the endianness is always the same
and let's assume the reason is that the origin of the data is internal to
the application (I know, that's a lot of assumptions :) ). Then...
while yours is guaranteed to need LSB-first.
Does .NET run on any big-endian systems? If the data originates from
within the application, are there true .NET scenarios where code that
assumes little-endian wouldn't work?

Until Mono has 100% parity with .NET (which I assume will never
happen...another assumption, I know :) ), I wouldn't consider it a
legitimate concern, even if it does run on a big-endian system (being
open-source, I assume it eventually will even if it doesn't now...does
Mono work on PowerPC-based Macs?)
Also you need some unsigned casts in that
expression to prevent sign-extension of the LSB from overwriting the MSB.
Or just masking would work too.

That said, in C something as simple as "tmpshort = *((short *)(pTmpDataIn
+ 1));" should have worked fine. There wasn't really a need to call
memcpy _or_ to manipulate the individual bytes of the original data.

If we're going to deconstruct the original C, we might as well do a
complete job. :)

Pete
Dec 31 '07 #9
Ben Voigt [C++ MVP] wrote:
"Arne Vajhøj" <ar**@vajhoej.dkwrote in message
news:47***********************@news.sunsite.dk...
>DatelMonkey99 wrote:
>>I have some c++ code that I am converting to C#. What I need to convert
is the following:

memcpy(&tmpshort, (pTmpDataIn+1), 2); This should copy two bytes of an
char* to an int which then gets used elsewhere. I am having trouble
coming up with how to approach.
I am not even sure that I understand why memcpy was used in C.

tmpshort = (short)((pTmpDataIn[2] << 8) | pTmpDataIn[1]);

There's a potential endianness difference here. memcpy is guaranteed to
work with the local processor endianness in the buffer, while yours is
guaranteed to need LSB-first.
I am guessing at x86 architecture ...

:-)
Also you need some unsigned casts in that
expression to prevent sign-extension of the LSB from overwriting the MSB.
bytes are unsigned in C#, so I assume that is OK as is.

Arne
Dec 31 '07 #10
Peter Duniho wrote:
On Mon, 31 Dec 2007 12:19:53 -0800, Ben Voigt [C++ MVP]
<rb*@nospam.nospamwrote:
Does .NET run on any big-endian systems? If the data originates from
within the application, are there true .NET scenarios where code that
assumes little-endian wouldn't work?

Until Mono has 100% parity with .NET (which I assume will never
happen...another assumption, I know :) ), I wouldn't consider it a
legitimate concern, even if it does run on a big-endian system (being
open-source, I assume it eventually will even if it doesn't now...does
Mono work on PowerPC-based Macs?)
Mono runs at MacOS X/PPC, Solaris SPARC, Linux/PPC and
Linux/IBM mainframe.

But I am sure that Linux/x86 is by far the most used
platform for Mono.

I do recall reading about a Mono on MacOS X problem, so it is
used. The other I have never heard about.
>Also you need some unsigned casts in that
expression to prevent sign-extension of the LSB from overwriting the MSB.

Or just masking would work too.
For byte which is unsigned ??
That said, in C something as simple as "tmpshort = *((short
*)(pTmpDataIn + 1));" should have worked fine. There wasn't really a
need to call memcpy _or_ to manipulate the individual bytes of the
original data.
Don't post that to comp.lang.c - some language lawyer will tell
you that it is undefined or implementation specific behavior (*).

Arne

*) On a few CPU architectures you will get a segmentation fault if
the address pTmpDataIn + 1 is not a multipla of sizeof(short).
The few includes SPARC.
Dec 31 '07 #11
On Dec 31 2007, 12:36 pm, "Peter Duniho"
<NpOeStPe...@nnowslpianmk.comwrote:
On Mon, 31 Dec 2007 12:19:53 -0800, Ben Voigt [C++ MVP]

<r...@nospam.nospamwrote:
I am not even sure that I understand why memcpy was used in C.
tmpshort = (short)((pTmpDataIn[2] << 8) | pTmpDataIn[1]);
There's a potential endianness difference here. memcpy is guaranteed to
work with the local processor endianness in the buffer,

Assuming the data was originally the same endianness as that being used.
That wouldn't be guaranteed if, for example, the data was previously
stored in a file or transmitted over a network or...

So let's assume that we can guarantee the endianness is always the same
and let's assume the reason is that the origin of the data is internal to
the application (I know, that's a lot of assumptions :) ). Then...
while yours is guaranteed to need LSB-first.

Does .NET run on any big-endian systems? If the data originates from
within the application, are there true .NET scenarios where code that
assumes little-endian wouldn't work?
..NET can run on the Xbox 360 (via XNA), which is a PowerPC platform.

Jesse
Jan 1 '08 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by hs | last post: by
5 posts views Thread by manya | last post: by
16 posts views Thread by Amarendra GODBOLE | last post: by
26 posts views Thread by Case | last post: by
70 posts views Thread by Rajan | last post: by
14 posts views Thread by ishmael4 | last post: by
39 posts views Thread by Martin Jørgensen | last post: by
3 posts views Thread by naren | last post: by
15 posts views Thread by Frederick Gotham | last post: by
18 posts views Thread by Mark | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.