I have a legacy VB6 application that has the following structure defined:
Public Type DrawDown
Date As Date
Amount As Currency
CapitaliseInterest As Boolean
End Type
An interop assembly is generated using tlbimp.exe
but the structure ends up as the following:
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct DrawDown
{
public DateTime Date;
[MarshalAs(UnmanagedType.Currency)]
public decimal Amount;
public short CapitaliseInterest;
}
I'm using .NET 4.0.
Why does the VB6 Boolean
get translated to a C# short
instead of a bool
?
VB6 uses the VARIANT_BOOL type,
find info and history about it here: BOOL vs. VARIANT_BOOL vs. BOOLEAN vs. boo
Off to the side came VARIANT_BOOL.
typedef short VARIANT_BOOL; define VARIANT_TRUE ((VARIANT_BOOL)-1) define VARIANT_FALSE ((VARIANT_BOOL)0) This was developed by the Visual Basic folks. Basic uses -1 to represent "true" and 0 to represent "false", and VARIANT_BOOL was designed to preserve this behavior.
Because it is one.
VB6 bools are 16-bit values where 0 is false and any non-zero is true, but something set to true is set to -1 (0xFFFF). This way a lot of combinations of bools with numbers works well with VB6 because x AND TRUE
gives x
, x OR FALSE
gives x
, x AND FALSE
gives FALSE
and so on, with the same logic for bit-wise and boolean operators. Unfortunately it also means that 4 AND 2
is false despite that being TrueThing AND OtherTrueThing
, so cautious VB6 coders didn't over-rely upon this, but used CBool
to force the value to be either 0 or -1.
In general we have the choice of using natural machine size for the machine-processing speed versus using a single byte as it's the smallest addressable unit and hence gives a size advantage. Back when the natural-size on 16-bit machines was, well 16-bits of course, the balance went more in favour of going for the natural size than today when we've 32-bit and 64-bit machines. Visual Basic 1.0 ran on DOS and Windows 3.0 which could run on Intel 80286 16-bit processors, so it's not that strange a choice.
In the COM world, we have VARIANT_BOOL, which is just another way of saying "a bool, done the way VB6 does them", to allow for compatibility across langauges. The closest thing in C# would be either short
or ushort
, and if we cared only about C# we could pick either. Firstly though, we tend to use signed more than unsigned values, which would lean us toward short
, but also ushort
is not a CLS-compliant type, and there's hardly any point introducing an incompatibility with other .NET languages in obtaining compatibility with COM! Hence short
is the clear choice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With