为什么COM Interop将VB6布尔值视为C#Short?

时间:2012-01-25 22:50:13

标签: c# .net com vb6 com-interop

我有一个遗留的VB6应用程序,它定义了以下结构:

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

使用tlbimp.exe生成互操作程序集,但结构最终如下:

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

我正在使用.NET 4.0。

为什么VB6 Boolean被转换为C#short而不是bool

4 个答案:

答案 0 :(得分:12)

VB6使用VARIANT_BOOL类型

在此处查找有关它的信息和历史记录:BOOL vs. VARIANT_BOOL vs. BOOLEAN vs. boo

  

一边是VARIANT_BOOL。

     

typedef short VARIANT_BOOL;定义VARIANT_TRUE((VARIANT_BOOL)-1)   定义VARIANT_FALSE((VARIANT_BOOL)0)这是由开发的   Visual Basic的人。 Basic使用-1表示“true”,0表示   代表“假”,而VARIANT_BOOL旨在保留这一点   行为。

答案 1 :(得分:8)

因为它是一个。

VB6 bool是16位值,其中0为假,任何非零都为真,但设置为true的内容设置为-1(0xFFFF)。这样很多bool与数字的组合很适合VB6,因为x AND TRUE给出了xx OR FALSE给出了xx AND FALSE给出了FALSE依此类推,对于按位和布尔运算符使用相同的逻辑。不幸的是,这也意味着4 AND 2尽管是TrueThing AND OtherTrueThing是假的,所以谨慎的VB6编码器并没有过度依赖它,而是使用CBool强制该值为0或者-1

一般而言,我们可以选择使用自然机器尺寸来获得机器处理速度,而不是使用单个字节,因为它是最小的可寻址单元,因此具有尺寸优势。当16位机器的自然尺寸当然是16位时,当我们拥有32位和64位机器时,平衡更有利于自然尺寸。 Visual Basic 1.0在DOS和Windows 3.0上运行,可以在英特尔80286 16位处理器上运行,所以选择并不奇怪。

在COM世界中,我们有VARIANT_BOOL,这只是另一种说法“bool,按照VB6的方式完成它们”的方式,以实现语言的兼容性。 C#中最接近的是shortushort,如果我们只关心C#,我们也可以选择。首先,我们倾向于使用签名而不是无符号值,这会使我们倾向short,但ushort也不是符合CLS的类型,并且几乎没有任何一点引入与其他的不兼容。 NET语言获得与COM的兼容性!因此short是明确的选择。

答案 2 :(得分:2)

引擎盖下的Boolean本质上是一个短整数:

False = 0, True != 0

生成互操作程序集可解决此问题。

每个MSDN的文档。

  

4字节整数值,其中任何非零值表示true和0   代表错误。这是a中布尔字段的默认格式   平台调用中的结构和布尔参数。

答案 3 :(得分:1)

您可以将/ VariantBoolFieldToBool标志传递给tlbimp.exe,以使其生成C#bool成员而不是短片。

请参阅official documentation for tlbimp.exe