Почему COM Interop рассматривает логическое значение VB6 как C # Short? - PullRequest
4 голосов
/ 26 января 2012

У меня есть устаревшее приложение 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 ]

12 голосов
/ 26 января 2012

VB6 использует тип VARIANT_BOOL,

найти информацию и историю об этом здесь: BOOL против VARIANT_BOOL против BOOLEAN против Boo

В стороне пришел VARIANT_BOOL.

typedef short VARIANT_BOOL; определить VARIANT_TRUE ((VARIANT_BOOL) -1) define VARIANT_FALSE ((VARIANT_BOOL) 0) Это было разработано Visual Basic люди. Basic использует -1 для представления «истина» и 0 для представляют "ложь", и VARIANT_BOOL был разработан, чтобы сохранить это поведение.

8 голосов
/ 26 января 2012

Поскольку он равен единице.

Значения VB6 - это 16-разрядные значения, где 0 равно false, а любое ненулевое значение - true, но для чего-то, установленного на 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, которые могли работать на 16-разрядных процессорах Intel 80286, так что это не такой уж странный выбор.

В мире COM у нас есть VARIANT_BOOL, что является еще одним способом сказать«bool, сделано так, как это делает VB6», чтобы обеспечить совместимость между языками.Самая близкая вещь в C # будет либо short, либо ushort, и если бы мы заботились только о C #, мы могли бы выбрать либо.Во-первых, мы склонны использовать значения со знаком больше, чем без знака, что указывает на short, но также ushort не является CLS-совместимым типом, и вряд ли есть смысл вводить несовместимость с другими языками .NET при получении.совместимость с COM!Следовательно, short является очевидным выбором.

2 голосов
/ 26 января 2012

Boolean, под капотом, по сути, короткое целое число:

False = 0, True != 0

Создание сборки взаимодействия разрешает это.

Документация по MSDN по этому.

4-байтовое целочисленное значение, где любое ненулевое значение представляет истину и 0 представляет ложь. Это формат по умолчанию для логического поля в структура и логический параметр в платформе вызывают вызовы.

1 голос
/ 18 мая 2012

Вы можете передать флаг / VariantBoolFieldToBool в tlbimp.exe, чтобы он генерировал член C # bool вместо короткого.

См. Официальную документацию для tlbimp.exe

...