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

发布于 2024-12-29 01:14:50 字数 545 浏览 0 评论 0原文

我有一个遗留的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

生生不灭 2025-01-05 01:14:50

VB6 使用 VARIANT_BOOL 类型,

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

旁边是 VARIANT_BOOL。

typedef 短 VARIANT_BOOL;定义 VARIANT_TRUE ((VARIANT_BOOL)-1)
Define VARIANT_FALSE ((VARIANT_BOOL)0) 这是由
Visual Basic 的朋友们。 Basic 使用 -1 表示“true”,0 表示
代表“假”,而 VARIANT_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.

一袭白衣梦中忆 2025-01-05 01:14:50

因为它是一个。

VB6 布尔值是 16 位值,其中 0 为假,任何非零为真,但设置为 true 的内容会设置为 -1 (0xFFFF)。这样,许多布尔值与数字的组合都可以在 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 上运行,Windows 3.0 可以在 Intel 80286 16 位处理器上运行,所以这并不是一个奇怪的选择。

在 COM 世界中,我们有 VARIANT_BOOL,这只是“布尔值,按照 VB6 的方式完成”的另一种说法,以允许跨语言兼容。 C# 中最接近的东西是 shortushort,如果我们只关心 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 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.

农村范ル 2025-01-05 01:14:50

布尔值本质上是一个短整数:

False = 0, True != 0

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

有关此内容的文档,请参阅 MSDN

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

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

False = 0, True != 0

Generating the interop assembly resolves this.

Documentation per MSDN on this.

4-byte integer value where any nonzero value represents true and 0
represents false. This is the default format of a Boolean field in a
structure and of a Boolean parameter in platform invoke calls.

盗琴音 2025-01-05 01:14:50

您可以将 /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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文