memcpy char* in C#

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • =?Utf-8?B?RGF0ZWxNb25rZXk5OQ==?=

    #1

    memcpy char* in C#

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

    memcpy(&tmpshor t, (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
  • Peter Duniho

    #2
    Re: memcpy char* in C#

    On Thu, 27 Dec 2007 11:45:00 -0800, DatelMonkey99
    <datelmonkey@ne wsgroups.nospam wrote:
    I have some c++ code that I am converting to C#. What I need to convert
    is
    the following:
    >
    memcpy(&tmpshor t, (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.To Int16(pTmpDataI n, 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

    Comment

    • =?UTF-8?B?QXJuZSBWYWpow7hq?=

      #3
      Re: memcpy char* in C#

      DatelMonkey99 wrote:
      I have some c++ code that I am converting to C#. What I need to convert is
      the following:
      >
      memcpy(&tmpshor t, (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)((pTmpDa taIn[2] << 8) | pTmpDataIn[1]);

      Arne

      Comment

      • Walter Wang [MSFT]

        #4
        RE: memcpy char* in C#

        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.ToCharAr ray
        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.ReadInt 16, Marshal.ReadInt 32, etc. to read the unmanaged
        memory.

        Hope this helps.


        Regards,
        Walter Wang (wawang@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.

        Comment

        • =?Utf-8?B?RGF0ZWxNb25rZXk5OQ==?=

          #5
          RE: memcpy char* in C#

          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_cu rrentSocket.End Receive(asyn);

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

          // Extract the characters as a buffer
          System.Text.Dec oder d = System.Text.Enc oding.UTF8.GetD ecoder();
          int charLen = d.GetChars(sock etData.dataBuff er, 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 (SessionMessage Id is the enum / pMessageIn in the
          unsigned char *)
          msgID = (SessionMessage Id)*pMessageIn;

          //Copy the next two bytes to get the size of the message
          memcpy(&tmpshor t, (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.ToCharAr ray
          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.ReadInt 16, Marshal.ReadInt 32, etc. to read the unmanaged
          memory.
          >
          Hope this helps.
          >
          >
          Regards,
          Walter Wang (wawang@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.
          >
          >

          Comment

          • =?UTF-8?B?QXJuZSBWYWpow7hq?=

            #6
            Re: memcpy char* in C#

            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.Binar yReader class ?

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

            Arne

            Comment

            • Peter Duniho

              #7
              Re: memcpy char* in C#

              On Fri, 28 Dec 2007 05:55:00 -0800, DatelMonkey99
              <datelmonkey@ne wsgroups.nospam wrote:
              [...]
              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 (SessionMessage Id is the enum / pMessageIn in the
              unsigned char *)
              msgID = (SessionMessage Id)*pMessageIn;
              >
              //Copy the next two bytes to get the size of the message
              memcpy(&tmpshor t, (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.dat aBuffer) 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

              Comment

              • Ben Voigt [C++ MVP]

                #8
                Re: memcpy char* in C#


                "Arne Vajhøj" <arne@vajhoej.d kwrote in message
                news:47743bd4$0 $90271$14726298 @news.sunsite.d k...
                DatelMonkey99 wrote:
                >I have some c++ code that I am converting to C#. What I need to convert
                >is the following:
                >>
                >memcpy(&tmpsho rt, (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)((pTmpDa taIn[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

                Comment

                • Peter Duniho

                  #9
                  Re: memcpy char* in C#

                  On Mon, 31 Dec 2007 12:19:53 -0800, Ben Voigt [C++ MVP]
                  <rbv@nospam.nos pamwrote:
                  >I am not even sure that I understand why memcpy was used in C.
                  >>
                  >tmpshort = (short)((pTmpDa taIn[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...anothe r 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

                  Comment

                  • =?ISO-8859-1?Q?Arne_Vajh=F8j?=

                    #10
                    Re: memcpy char* in C#

                    Ben Voigt [C++ MVP] wrote:
                    "Arne Vajhøj" <arne@vajhoej.d kwrote in message
                    news:47743bd4$0 $90271$14726298 @news.sunsite.d k...
                    >DatelMonkey9 9 wrote:
                    >>I have some c++ code that I am converting to C#. What I need to convert
                    >>is the following:
                    >>>
                    >>memcpy(&tmpsh ort, (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)((pTmpDa taIn[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

                    Comment

                    • =?UTF-8?B?QXJuZSBWYWpow7hq?=

                      #11
                      Re: memcpy char* in C#

                      Peter Duniho wrote:
                      On Mon, 31 Dec 2007 12:19:53 -0800, Ben Voigt [C++ MVP]
                      <rbv@nospam.nos pamwrote:
                      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...anothe r 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.


                      Comment

                      • Jesse McGrew

                        #12
                        Re: memcpy char* in C#

                        On Dec 31 2007, 12:36 pm, "Peter Duniho"
                        <NpOeStPe...@nn owslpianmk.comw rote:
                        On Mon, 31 Dec 2007 12:19:53 -0800, Ben Voigt [C++ MVP]
                        >
                        <r...@nospam.no spamwrote:
                        I am not even sure that I understand why memcpy was used in C.
                        >
                        tmpshort = (short)((pTmpDa taIn[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

                        Comment

                        Working...