CLS-совместимые типы в ассемблере P / Invoke - PullRequest
1 голос
/ 21 сентября 2010

Имея отдельную вспомогательную сборку, содержащую только декларации P / Invoke для устаревших сторонних компонентов, мне интересно, какой из этих двух способов является The Better One ™, если сборка должна быть помечена как CLS-совместимая:

  • Используйте Int32 в публичном P / Invoke объявлении, где неуправляемое объявление имеет unsigned int.
  • Используйте UInt32 в внутреннем P / Invoke объявлении, гденеуправляемое объявление имеет unsigned int и заключает его в открытый метод, который принимает Int32 и преобразует его в UInt32 при вызове внутреннего метода.

Каковы их плюсы и минусы?

Ответы [ 2 ]

1 голос
/ 21 сентября 2010

Маршаллер P / Invoke не будет жаловаться, когда uint становится слишком большим, вы просто получите отрицательный int. Дополнительный слой позволяет использовать ключевое слово checked для создания исключения OverflowException. Что довольно желательно.

Стоит ли это хлопот - вопрос второстепенный. Многие API, такие как Win32, используют unsigned в качестве логического ограничения. Как длина строки или размер блока памяти, она никогда не может быть отрицательной. На практике такое число никогда не может переполниться. Потому что невозможно выделить столько памяти. Я не помню, чтобы когда-то работал в API, где это был slam-dunk, который нужно использовать. Поэтому я думаю, что вы в порядке, просто используя прямое объявление pinvoke с целыми числами.

1 голос
/ 21 сентября 2010

Я не думаю, что вы бы поступили правильно, если бы выбрали вариант 1. Int32 может достигать 2 147 483 647.Принимая во внимание, что неподписанный int достигает 4 294 967 295.Пока вы ЗНАЕТЕ, что вам не нужны никакие значения свыше 2 миллиардов, это не имеет значения.Но чтобы быть технически правильным, общедоступный интерфейс должен предоставлять больший тип и выполнять проверку границ, чтобы убедиться, что он вписывается в беззнаковое целое и выдает исключение, если это не так.Int64 сделает (9 223 372 036 854 775 807).

...