473,326 Members | 2,134 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

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 4039
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: hs | last post by:
Is the following correct? void foo(int len, char* val) { .. .. .. unsigned char* string = (unsigned char*) new char ; memcpy(string, val, len); ..
5
by: manya | last post by:
Ok, it's been a while since I've done the whole memcpy stuff with C++ and I'm having a hard time remembering everything. I hope, however, that you can help me with my problem. I memcpy a...
16
by: Amarendra GODBOLE | last post by:
Hi, I am a bit confused over the correct usage of memcpy(). Kindly help me clear the confusion. The linux manpage for memcpy(3) gives me the following prototype of memcpy(3): #include...
26
by: Case | last post by:
#include <string.h> int i; /* 4-byte == 4-char */ char data = { 0x78, 0x56, 0x34, 0x12 }; int main() { memcpy(&i, data, 4); /*
70
by: Rajan | last post by:
Hi, I am trying to simulate a memcpy like this void* mem_cpy(void* dest, void* src, int bytes) { dest = malloc(bytes); } Now if I want to copy the bytes from src to dest, how do I copy these...
14
by: ishmael4 | last post by:
hello! i've go two structures: --cut here-- const unsigned int max_pkg_data=5000; typedef struct pkg_ { short int info; short int size;
39
by: Martin Jørgensen | last post by:
Hi, I'm relatively new with C-programming and even though I've read about pointers and arrays many times, it's a topic that is a little confusing to me - at least at this moment: ---- 1)...
3
by: naren | last post by:
Iam not getting the correct pros and cons of the strcpy() and memcpy() some where i read for short strings strcpy is faster and for large strings memcpy is faster.. in strcpy() there is a single...
15
by: Frederick Gotham | last post by:
What's the canonical way to copy an array in C++? If we're copying a POD, we can use memcpy (but there could be a more efficient alternative if we know that the blocks are suitably aligned). ...
18
by: Mark | last post by:
Hi List, I want to write a function to copy some data out of a hardware buffer. The hardware can change the contents of this buffer without it being written to by my function. I want to use...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.