When is a LONG not a long?

Answer: When PInvoke is involved.

I ran across a common error today on stackoverflow regarding P/Invoke that is worth blogging about.  The question regarded the translation of a native API with a parameter of type LONG.  The user mistakenly used the .Net long type as the parameter.  The error is that a C++ LONG is not the same as a .Net long.

When talking about types and PInvoke it's easier to discuss byte size and signed-ness than type names.  Otherwise confusion around long and short crop up.  Really there are four integer byte sizes each of which can be signed or unsigned: 1,2,4 and 8

The problem the user encountered is the C++ long is 4 byte signed and .Net long is 8 byte signed.  PInvoke requires the parameters to have the same size.  Below is a quick table of the various types in C++ and .Net.

  • 1 byte

    • C++ - char, __int8, BYTE, BOOLEAN

    • .Net - byte

  • 2 byte

    • C++ - wchar, __int16, short, WORD

    • .Net - char, short

  • 4 byte

    • C++ - int, LONG, long, __int32, DWORD

    • .Net - int

  • 8 byte


    • .Net - long

Based on this table when translating a C++ LONG, you should use a .Net int.

Edit1: Moved C++ short to 2 byte, added several other C++ types. (thanks Raymond)

Skip to main content