Print
Category: Compiler and Linker
Hits: 2215

Lately we had a problem passing an enumeration as parameter of an interface method. We had following configuration: The application was written in Borland C++ using the Zeus-Framework. We were using a native COM interface where its implementation was written in Visual Studio C++. The method we were calling looked something like


virtual HRESULT STDMETHODCALLTYPE methodA(LPWSTR szVar1, EnumTyp eType, LPWSTR __RPC_FAR* szRetval) = 0;

Every time we called this method with a valid enumeration value, we got some weird value on the VC++ side.

The problem was that Borland uses dynamically sized enumeration, witch means the compiler looks at the value range first and then allocated 8bit, 16bit or 32bit for the enumeration. So when pushing the arguments to the stack, first the szRetval was pushed using EAX register (32bit). Then the second argument is pushed using the AX register only. The upper 16bits are not overwritten, therefore the upper part is dirty. On the otherside reading from the stack (in VC++ module) all 32 bit are read, since this compiler handles enumerations as 32bit in general.

To fix this problem, the borland compiler must be used with the option -b. Now all enumerations are handled as int-values (32bit on 32bit platforms). I don't know if the whole thing works for 64bit platforms in the same way.

For all Borland projects using Zeus-Framework I added following lines to BCB_Config.h:


//The compiler option -b must be set for BCB projects otherwise enum's are not
// handled properly passing as interface method parameters. Specially for VC
// projects the problem is known, since they handle enums as int.
#pragma defineonoption ENUM_AS_INT -b

#ifndef ENUM_AS_INT
  #error Compiler does not handle enums as int (Option -b not set). ...
#endif