Is it safe to use enums across interop boundaries?

2019-09-20 17:09发布

问题:

I'm writing a set of DLLs which allows other developers write their own DLL as an extension. In the Delphi code, I widely use enums, and enum sets. I use enums through DLLs. I know I can safely use an enum through a DLL across different projects compiled with Delphi. However, I'm not sure about how adaptable it is across various languages.

Is it safe to use enums through a DLL while supporting other various languages? Or should I cast it as an integer instead?

回答1:

Enums need to be passed as integers (Word or DWORD), and you should use the compiler directive {$MINENUMSIZE} (AKA {$Z}) to ensure that they're the proper size. The Delphi compiler will use different sizes based on the number of enum values unless you do so.

If you're planning to interop with C/C++ code on the Windows OS, use {$MINENUMSIZE 4}.

The documentation I linked above addresses interop with C/C++ - see the third paragraph:

The $Z directive controls the minimum storage size of Delphi enumerated types.

An enumerated type is stored as an unsigned byte if the enumeration has no more than 256 values, and if the type was declared in the {$Z1} state (the default). If an enumerated type has more than 256 values, or if the type was declared in the {$Z2} state, it is stored as an unsigned word. Finally, if an enumerated type is declared in the {$Z4} state, it is stored as an unsigned double word.

The {$Z2} and {$Z4} states are useful for interfacing with C and C++ libraries, which usually represent enumerated types as words or double words.