Translating a bitwise operation from C++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John Dann

    #1

    Translating a bitwise operation from C++

    I'm trying to generate a 4-byte unsigned integer in VB2005 that
    encodes a number of bit-level variables. What I need to do is to be
    able to compute a value for the uint that is based on specific values
    for the constituent variables; the unit can then be passed to an
    external DLL, which requires a function parameter in this form.

    Unfortunately the only documentation I have for the external DLL is in
    (I think) C++, which I'm struggling to understand. The C++ code for
    the procedure to create a value for the number is:

    MakeNumber(CV, DU, DT, ST, SID)

    ( ((CV) & 0x1F) | (((DU) & 0x1F)<<5) | (((DT) & 0x1F)<<10) |

    (((ST) & 0xFF)<<16) | (((SID) & 0xFF)<<24) )

    (The 3 lines above are all on a single line in the original code.)

    So, the procedure is encoding values for the 5 variables CV, DU, DT,
    ST, SID) in assembling the final uint.

    Now I can see the gist of what's being done here and can spot the
    bitwise operators but I've got 2 questions about how to translate this
    procedure into VB2005:

    1. Is there some equivalent assembly procedure that I can use in
    VB2005 and if so what would the exact syntax be? For example is there
    any equivalent of what seems to be the | operator?

    2. What data type should I use for the values held in CV, DU etc?
    UShort maybe?

    Many thanks for any help.
  • Michael M.

    #2
    Re: Translating a bitwise operation from C++

    The data 0xff is the same as 11111111 in binrary and would be a single byte
    so the data type is byte or Char or short I think, the operators convert
    something like this:

    | = OR
    & = AND
    << = Shift bit left (probably a function for this in VB.net)

    In C++ a single operator means a bitwise action to do on a value and a
    double operator is used in logical comparsions the following below would be
    used in if statements to compare things:

    ||
    ==
    &&

    Regards,

    Mike.

    "John Dann" <news@prodata.c o.ukwrote in message
    news:p96j535587 s8ljdq49g2lh9pv c707nhhif@4ax.c om...
    I'm trying to generate a 4-byte unsigned integer in VB2005 that
    encodes a number of bit-level variables. What I need to do is to be
    able to compute a value for the uint that is based on specific values
    for the constituent variables; the unit can then be passed to an
    external DLL, which requires a function parameter in this form.
    >
    Unfortunately the only documentation I have for the external DLL is in
    (I think) C++, which I'm struggling to understand. The C++ code for
    the procedure to create a value for the number is:
    >
    MakeNumber(CV, DU, DT, ST, SID)
    >
    ( ((CV) & 0x1F) | (((DU) & 0x1F)<<5) | (((DT) & 0x1F)<<10) |
    >
    (((ST) & 0xFF)<<16) | (((SID) & 0xFF)<<24) )
    >
    (The 3 lines above are all on a single line in the original code.)
    >
    So, the procedure is encoding values for the 5 variables CV, DU, DT,
    ST, SID) in assembling the final uint.
    >
    Now I can see the gist of what's being done here and can spot the
    bitwise operators but I've got 2 questions about how to translate this
    procedure into VB2005:
    >
    1. Is there some equivalent assembly procedure that I can use in
    VB2005 and if so what would the exact syntax be? For example is there
    any equivalent of what seems to be the | operator?
    >
    2. What data type should I use for the values held in CV, DU etc?
    UShort maybe?
    >
    Many thanks for any help.

    Comment

    • Michael C

      #3
      Re: Translating a bitwise operation from C++

      "John Dann" <news@prodata.c o.ukwrote in message
      news:p96j535587 s8ljdq49g2lh9pv c707nhhif@4ax.c om...
      MakeNumber(CV, DU, DT, ST, SID)
      >
      ( ((CV) & 0x1F) | (((DU) & 0x1F)<<5) | (((DT) & 0x1F)<<10) |
      >
      (((ST) & 0xFF)<<16) | (((SID) & 0xFF)<<24) )
      (CV And &h1f) or ((DU and &h1f) * 32) or ((DT And &h1f) * 1024) or ((ST And
      &hff) * 65536) or ((SID And &hff) * 16777216)

      You might have issues with the last bracketed section because I presume this
      will default to signed int. You might need to convert them to unsigned int
      and then back.
      2. What data type should I use for the values held in CV, DU etc?
      UShort maybe?
      It is a macro so not specified. Most likely they used 32 bit int.

      Michael


      Comment

      • John Dann

        #4
        Re: Translating a bitwise operation from C++


        On Mon, 28 May 2007 11:03:16 +1000, "Michael C" <nospam@nospam. com>
        wrote:
        >(CV And &h1f) or ((DU and &h1f) * 32) or ((DT And &h1f) * 1024) or ((ST And
        >&hff) * 65536) or ((SID And &hff) * 16777216)
        >
        >You might have issues with the last bracketed section because I presume this
        >will default to signed int. You might need to convert them to unsigned int
        >and then back.
        >
        >2. What data type should I use for the values held in CV, DU etc?
        >UShort maybe?
        >
        >It is a macro so not specified. Most likely they used 32 bit int.
        >
        Thanks for the response. Actually, I do have a bit more info on the
        data types in the original - just didn't include it in the original
        question in the interests of brevity (and also because I didn't fully
        understand it!). The relevant details are below. (These details define
        the memory structure that the number I'm trying to generate needs to
        access, so the bit structures of the two integers must presumably
        mirror one another.)

        struct VarA // the same size as a UINT
        {
        unsigned int CV: 5;
        unsigned int DU: 5;
        unsigned int DT: 5;
        unsigned int reserved : 1;

        unsigned int ST : 8;
        unsigned int SID: 8;

        bool IsCurrentVariab le(); // is the ID valid for current data?
        bool IsHiLowVariable (); // is ID valid for Hi/Low data?

        };

        union ID
        {
        DWORD id;
        VarA fields;
        };

        I've been able to make some progress in getting this working in that
        the code for creating the 4-byte uint compiles and the resulting
        number does return a value when passed in the function call, but
        unfortuantely it's not the right value! So I still have work to do and
        any further ideas would be very helpful.

        The structure of my code at present is:

        Dim result as ULong
        Dim CV, DU, DT, ST, SID as UShort

        result = _
        (CV And &h1f) or ((DU and &h1f) * 32) or ((DT And &h1f) * 1024) or _
        ((ST And &hff) * 65536) or ((SID And &hff) * 16777216)

        (I've also tried declaring CV etc as UInteger but no change - result
        is identical and still wrong.)


        I wasn't sure exactly what was meant by:
        >You might have issues with the last bracketed section because I presume this
        >will default to signed int. You might need to convert them to unsigned int
        >and then back.
        Could someone spell out just what might need converting please, ie the
        whole result value or the last bracketed part?

        Comment

        • Michael C

          #5
          Re: Translating a bitwise operation from C++

          "John Dann" <news@prodata.c o.ukwrote in message
          news:31bl53lepb 472ric686vpdhg8 45et8u9mi@4ax.c om...
          Thanks for the response. Actually, I do have a bit more info on the
          data types in the original - just didn't include it in the original
          question in the interests of brevity (and also because I didn't fully
          understand it!). The relevant details are below. (These details define
          the memory structure that the number I'm trying to generate needs to
          access, so the bit structures of the two integers must presumably
          mirror one another.)
          That makes sense although I'm not sure you could duplicate this in vb.net.
          You could try using the FieldOffset attribute.
          I've been able to make some progress in getting this working in that
          the code for creating the 4-byte uint compiles and the resulting
          number does return a value when passed in the function call, but
          unfortuantely it's not the right value! So I still have work to do and
          any further ideas would be very helpful.
          >
          The structure of my code at present is:
          >
          Dim result as ULong
          Dim CV, DU, DT, ST, SID as UShort
          >
          result = _
          (CV And &h1f) or ((DU and &h1f) * 32) or ((DT And &h1f) * 1024) or _
          ((ST And &hff) * 65536) or ((SID And &hff) * 16777216)
          >
          (I've also tried declaring CV etc as UInteger but no change - result
          is identical and still wrong.)
          Everything should be uinteger I believe (int is 32bit in VB I presume). To
          find the problem try giving CV a non-zero value and everything else a zero
          value. Do you get the expected result? If so then try the same thing for DU
          and then DT etc.
          I wasn't sure exactly what was meant by:
          >
          >>You might have issues with the last bracketed section because I presume
          >>this
          >>will default to signed int. You might need to convert them to unsigned int
          >>and then back.
          >
          Could someone spell out just what might need converting please, ie the
          whole result value or the last bracketed part?
          With vb it will default to signed integer in most cases. This can cause
          problems when doing math like this because the most significant bit is the
          sign. To avoid errors you need to define everything as unsigned int. Eg:
          &hffff * &h10000 should give &hffff0000 but will give an error if unsigned
          is not used.


          Comment

          Working...