5

I have a manager wrapper for a native library -- the native library is C++ with an exported C interface, and I use P/Invoke on the managed to side to achieve the interop. I am in control of both the managed and native code.

There's an enumeration in the native code that has a corresponding enumeration in managed code, something like this:

// C#
public enum ErrorCode {
  None = 0,
  General = 1,
  BadThings = 2,
  HardDriveWasRemoved = 3,
}

// C++
enum ERROR_CODE {
  ERROR_CODE_NONE = 0,
  ERROR_CODE_GENERAL = 1,
  ERROR_CODE_BAD_THINGS = 2,
  ERROR_CODE_HARD_DRIVE_REMOVED = 3,
}

These enumerations need to be kept in sync, because the enumeration values are passed back and forth between managed and native code; an incorrect mapping between them causes subtle failures that aren't always immediately obvious.

Does anybody have any clever (but relatively light-weight) techniques for either (a) automatically keeping these enumerations in sync, or (b) providing a warning/error/failure as early as possible that the enumerations are out of sync?

  • 2
    Related question with answers but none chosen as the answer: http://stackoverflow.com/questions/1947576/shared-common-definitions-across-c-c-unmanaged-and-managed-c-code – Erik Noren Feb 04 '11 at 18:56
  • Ah, thanks, I missed that one in my initial search due to the lack of the term 'enumeration' in the title I guess. –  Feb 04 '11 at 19:09
  • 1
    Dupe of the one Erik found, and also http://stackoverflow.com/questions/3457646/using-enum-in-c-and-c-via-c-header and http://stackoverflow.com/questions/954321/is-it-possible-to-share-an-enum-declaration-between-c-and-unmanaged-c and http://stackoverflow.com/questions/3240263/sharing-an-enum-from-c-c-cli-and-c .. and those were just the ones found by searching for "[c++] [c#] enum" – Ben Voigt Feb 04 '11 at 19:54

2 Answers2

5

Place them into a separate C# file, #include from C++ side. #define away all the C# fluff (like the initial public). Like this:

#define public
#include "enums.cs"
#undef public
Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • Pretty slick - though you'd still be responsible for keeping the two in sync within the file, shouldn't be too much of a problem. – 3Dave Feb 04 '11 at 20:27
  • 1
    Do you really need two different naming conventions? I'd say that the importance of keeping the two in sync trumps convention. If not sure, go with the C++ one. CONSTANTS_ARE_MEANT_TO_BE_LIKE_THIS. AndCamelCaseDenotesManyOtherThingsAlready. – Seva Alekseyev Feb 04 '11 at 20:34
1

Reminds me of a music joke: How do you get two piccolo players to play in tune? A: Shoot one.

Could you just register the native DLL for COM, then reference and use the C++ enum in the C# code? I realize the naming conventions are a little off, but overall, just having one enum seems the simplest way to achieve what you want.

KeithS
  • 70,210
  • 21
  • 112
  • 164