为什么 COM Interop 将 VB6 布尔值视为 C# Short?
我有一个遗留的 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
?
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
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
VB6 使用 VARIANT_BOOL 类型,
请在此处查找有关它的信息和历史记录: BOOL 与 VARIANT_BOOL 与 BOOLEAN 与 boo
VB6 uses the VARIANT_BOOL type,
find info and history about it here: BOOL vs. VARIANT_BOOL vs. BOOLEAN vs. boo
因为它是一个。
VB6 布尔值是 16 位值,其中 0 为假,任何非零为真,但设置为 true 的内容会设置为 -1 (0xFFFF)。这样,许多布尔值与数字的组合都可以在 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 上运行,Windows 3.0 可以在 Intel 80286 16 位处理器上运行,所以这并不是一个奇怪的选择。
在 COM 世界中,我们有 VARIANT_BOOL,这只是“布尔值,按照 VB6 的方式完成”的另一种说法,以允许跨语言兼容。 C# 中最接近的东西是
short
或ushort
,如果我们只关心 C#,我们可以选择其中之一。首先,我们倾向于使用有符号的值而不是无符号的值,这会让我们倾向于short
,但ushort
也不是符合 CLS 的类型,而且几乎没有任何意义在获得与 COM 的兼容性时引入了与其他 .NET 语言的不兼容性!因此,short
是明智的选择。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
givesx
,x OR FALSE
givesx
,x AND FALSE
givesFALSE
and so on, with the same logic for bit-wise and boolean operators. Unfortunately it also means that4 AND 2
is false despite that beingTrueThing AND OtherTrueThing
, so cautious VB6 coders didn't over-rely upon this, but usedCBool
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
orushort
, 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 towardshort
, but alsoushort
is not a CLS-compliant type, and there's hardly any point introducing an incompatibility with other .NET languages in obtaining compatibility with COM! Henceshort
is the clear choice.布尔值本质上是一个短整数:
生成互操作程序集可以解决此问题。
有关此内容的文档,请参阅 MSDN。
The
Boolean
, under the hood, is essentially a short integer:Generating the interop assembly resolves this.
Documentation per MSDN on this.
您可以将 /VariantBoolFieldToBool 标志传递给 tlbimp.exe,使其生成 C# bool 成员而不是短整型。
请参阅 tlbimp.exe 的官方文档
You can pass the /VariantBoolFieldToBool flag to tlbimp.exe to make it generate a C# bool member instead of the short.
See the official documentation for tlbimp.exe