我有一个遗留的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
?
答案 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
给出了x
,x OR FALSE
给出了x
,x 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#中最接近的是short
或ushort
,如果我们只关心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成员而不是短片。