Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. Visual Basic
  4. Unsigned Integers and Marshal.ReadInt32()

Unsigned Integers and Marshal.ReadInt32()

Scheduled Pinned Locked Moved Visual Basic
question
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • V Offline
    V Offline
    VFaul
    wrote on last edited by
    #1

    I'm calling a function in an unmanaged DLL. It is returning data as unsigned integers. I am using Marshal.ReadInt32() to marshal the data. I am getting an "Arithmetic overflow" exception when it trys to put the signed integer data into the managed unsigned integer variable: Dim uiData as UInt32 = Marshal.ReadInt32(ipBuffer) The exception only happens when the data has the most significant bit set (the "sign" bit). If Marshal.ReadUInt32() existed, obviously I would use that. Since it does not exist, I am marshaling the four bytes individually using Marshal.ReadByte() and constructing the unsigned integer. Is there a better way to do this?

    D 1 Reply Last reply
    0
    • V VFaul

      I'm calling a function in an unmanaged DLL. It is returning data as unsigned integers. I am using Marshal.ReadInt32() to marshal the data. I am getting an "Arithmetic overflow" exception when it trys to put the signed integer data into the managed unsigned integer variable: Dim uiData as UInt32 = Marshal.ReadInt32(ipBuffer) The exception only happens when the data has the most significant bit set (the "sign" bit). If Marshal.ReadUInt32() existed, obviously I would use that. Since it does not exist, I am marshaling the four bytes individually using Marshal.ReadByte() and constructing the unsigned integer. Is there a better way to do this?

      D Offline
      D Offline
      Dave Kreskowiak
      wrote on last edited by
      #2

      VFaul wrote:

      Dim uiData as UInt32 = Marshal.ReadInt32(ipBuffer) The exception only happens when the data has the most significant bit set (the "sign" bit). If Marshal.ReadUInt32() existed, obviously I would use that. Since it does not exist, I am marshaling the four bytes individually using Marshal.ReadByte() and constructing the unsigned integer. Is there a better way to do this?

      No, not really. You're reading a four byte value as signed 32-bit integer (31 bits plus the sing bit), which means the number read can be a negative number, not positive. When the conversion to Unsigned is attempted, it can't convert a negative number, so you get the exception. You can convert any number of bytes using the BitConverter class. You still need to read the four bytes into an array, but you can use the BitConverter.ToUInt32[^] method to do this, probably easier than you're doing it now.

      A guide to posting questions on CodeProject[^]
      Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
           2006, 2007

      V 1 Reply Last reply
      0
      • D Dave Kreskowiak

        VFaul wrote:

        Dim uiData as UInt32 = Marshal.ReadInt32(ipBuffer) The exception only happens when the data has the most significant bit set (the "sign" bit). If Marshal.ReadUInt32() existed, obviously I would use that. Since it does not exist, I am marshaling the four bytes individually using Marshal.ReadByte() and constructing the unsigned integer. Is there a better way to do this?

        No, not really. You're reading a four byte value as signed 32-bit integer (31 bits plus the sing bit), which means the number read can be a negative number, not positive. When the conversion to Unsigned is attempted, it can't convert a negative number, so you get the exception. You can convert any number of bytes using the BitConverter class. You still need to read the four bytes into an array, but you can use the BitConverter.ToUInt32[^] method to do this, probably easier than you're doing it now.

        A guide to posting questions on CodeProject[^]
        Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
             2006, 2007

        V Offline
        V Offline
        VFaul
        wrote on last edited by
        #3

        Yes, I understand why the exception is occurring. What baffles me is that there aren't unsigned marshaling methods: Marshal.ReadUInt16(), ReadUIn32(), and ReadUInt64()!? I'm being forced to do four ReadByte() calls when one call to ReadUInt32() is all I would need.

        D 1 Reply Last reply
        0
        • V VFaul

          Yes, I understand why the exception is occurring. What baffles me is that there aren't unsigned marshaling methods: Marshal.ReadUInt16(), ReadUIn32(), and ReadUInt64()!? I'm being forced to do four ReadByte() calls when one call to ReadUInt32() is all I would need.

          D Offline
          D Offline
          Dave Kreskowiak
          wrote on last edited by
          #4

          VFaul wrote:

          What baffles me is that there aren't unsigned marshaling methods: Marshal.ReadUInt16(), ReadUIn32(), and ReadUInt64()!? I'm being forced to do four ReadByte() calls when one call to ReadUInt32() is all I would need.

          Yep. After looking at the code for the Marshal class, ReadInt32 method, it's sort of obvious why. That method has but a single line of code that calls a function, ND_RI4, exported by mscoree.dll. This function reads a 4 byte value and returns an I4, or Int32. The only other exported functions that do this are:

          ND\_RI2  -  Returns a 16-bit signed integer
          ND\_RI4  -  Returns a 32-bit signed integer
          ND\_RI8  -  Returns a 64-bit signed integer
          

          and
          ND_RU1 - Returns a single byte

          There are counterpart functions that write values too, modeled after these "read" version. Sadly, it boils down to the CLR doesn't natively support what you want to do. I also looked into the possibility of using Marshal.ReadIntPtr, which returns a processor width pointer. On any non-x64 version of Windows, this always maps to a 32-bit unsigned integer. But, there is no conversion supplied to go from an IntPtr to a UInt, only a conversion to Int32 exists.

          A guide to posting questions on CodeProject[^]
          Dave Kreskowiak Microsoft MVP Visual Developer - Visual Basic
               2006, 2007

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups