为什么COM Interop将VB6布尔值视为C#Short
本文关键字:C#Short 布尔值 VB6 COM Interop 为什么 | 更新日期: 2023-09-27 18:21:31
我有一个遗留的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
?
VB6使用VARIANT_BOOL类型
在这里查找有关它的信息和历史:BOOL vs.VARIANT_BOOL vs.BOOLEAN vs.boo
旁边是VARIANT_BOOL。
typedef short VARIANT_BOOL;定义VARIANT_TRUE((VARIANT_BOOL)-1)define VARIANT_FALSE((VARIANT_BOOL)0)这是由Visual Basic用户。基本用法-1表示"true",0表示表示"false",VARIANT_BOOL旨在保留行为
因为它是一个。
VB6布尔值是16位值,其中0为假,任何非零为真,但设置为真的值设置为-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上,后者可以运行在Intel 80286 16位处理器上,所以选择它并不奇怪。
在COM世界中,我们有VARIANT_BOOL,这只是"一个BOOL,按照VB6的方式完成"的另一种说法,以允许跨语言的兼容性。C#中最接近的东西是short
或ushort
,如果我们只关心C#,我们可以选择其中之一。首先,我们倾向于使用有符号值而不是无符号值,这会使我们倾向于short
,但ushort
不是符合CLS的类型,在获得与COM的兼容性时,引入与其他.NET语言的不兼容性几乎没有任何意义!因此CCD_ 18是明确的选择。
Boolean
本质上是一个短整数:
False = 0, True != 0
生成互操作程序集可以解决此问题。
有关此的MSDN文档。
4字节整数值,其中任何非零值表示true和0表示错误。这是结构和平台调用中的布尔参数。
您可以将/VariantBoolFieldToBool标志传递给tlbimp.exe,使其生成C#布尔成员,而不是short。
请参阅tlbimp.exe 的官方文档