Why does COM Interop treat VB6 Boolean as C # Short?

I have an outdated VB6 application that has the following structure:

Public Type DrawDown Date As Date Amount As Currency CapitaliseInterest As Boolean End Type 

The interop collection is created using tlbimp.exe , but the structure ends as follows:

 [StructLayout(LayoutKind.Sequential, Pack = 4)] public struct DrawDown { public DateTime Date; [MarshalAs(UnmanagedType.Currency)] public decimal Amount; public short CapitaliseInterest; } 

I am using .NET 4.0.

Why does VB6 Boolean translate to C # short instead of bool ?

+4
source share
4 answers

VB6 uses type VARIANT_BOOL,

find information and history about it here: BOOL vs VARIANT_BOOL vs BOOLEAN vs boo

Off to VARIANT_BOOL.

typedef short VARIANT_BOOL; define VARIANT_TRUE ((VARIANT_BOOL) -1) define VARIANT_FALSE ((VARIANT_BOOL) 0) It was developed by Visual Basic People. Basic uses -1 to represent true and 0 to represent false, and VARIANT_BOOL was designed to preserve this behavior.

+12
source

Because he is alone.

VB6 bools are 16-bit values, where 0 is false, and any non-zero value is true, but the value set to true is -1 (0xFFFF). Thus, many combinations of bools with numbers work 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-mud and boolean operators. Unfortunately, this also means that 4 AND 2 is false, although TrueThing AND OtherTrueThing , so careful VB6 encoders did not rely too much on it, but used CBool to force the value to be either 0 or -1.

In general, we have the choice of using the natural size of the machine for the processing speed compared to using a single byte, since this is the smallest addressable unit and, therefore, gives an advantage in size. Back when the natural size on 16-bit machines was, of course, 16-bit, of course, the balance went more in favor of switching to natural size than today, when we have 32-bit and 64-bit machines. Visual Basic 1.0 worked on DOS and Windows 3.0, which could run on 16-bit Intel 80286 processors, so this is not an odd choice.

In the COM world, we have VARIANT_BOOL, which is another way of saying “bool, done the way VB6 does” to ensure compatibility between langauges. The closest thing in C # will be either short or ushort , and if we only cared about C #, we could choose it. First, we tend to use signed values ​​more than unsigned to make us short , but ushort not a CLS-compatible type, and there is hardly any point representing incompatibility with other .NET languages ​​when receiving compatible with COM! Therefore, short is an obvious choice.

+8
source

Boolean , under the hood, is essentially a short integer:

 False = 0, True != 0 

Generating an interop assembly allows this.

MSDN documentation on this.

A 4-byte integer value, where any nonzero value represents true and 0 represents false. This is the default format for the boolean field in the structure and the Boolean parameter in platform invocation calls.

+2
source

You can pass the / VariantBoolFieldToBool flag to tlbimp.exe so that it generates a C # bool member instead of a short one.

See the official documentation for tlbimp.exe

+1
source

Source: https://habr.com/ru/post/1393060/


All Articles