К сожалению, я забыл одну вещь, когда делал этот ответ, и я не совсем уверен в этом. себя и что я не могу найти информацию в MSDN и Google и поиске переполнения стека.
В Windows API есть ряд мест, где вы используете отрицательное число или число, которое слишком велико, чтобы поместиться в целое число со знаком; например, CW_USEDEFAULT
, INVALID_HANDLE_VALUE
, GWLP_USERDATA
и т. д. В мире C все прекрасно и прекрасно: на помощь приходят правила целочисленного продвижения языка.
Но в Go я должен передать все свои аргументы функциям как uintptr
(что эквивалентно uintptr_t
в C). Возвращаемое значение из функции также возвращается таким образом, и тогда мне нужно будет сравнить. Go не поддерживает целочисленное преобразование и не позволяет преобразовывать константное выражение со знаком в беззнаковое во время компиляции.
Прямо сейчас у меня есть небольшая мешанина настроен для обработки этих констант в моей библиотеке пользовательского интерфейса. (Вот пример того, как это решение выглядит в действии.) Однако меня это решение не совсем устраивает; мне кажется, что он предполагает что-то о ЛПИ, и я хочу быть абсолютно уверенным в том, что делаю.
Итак, мой вопрос: как обрабатываются подписанные значения при их передаче функциям Windows API и как они обрабатываются при возврате?
Все мои константы сгенерированы автоматически (пример вывода). Автогенератор использует c ffi, который я бы не стал использовать для основного проекта, поскольку Я могу вызывать библиотеки DLL напрямую (это также упрощает кросс-компиляцию, по крайней мере, до конца года). Если бы я мог как-то использовать это, например, превратив все в переменную C-стороны формы
uintptr_t x_CONST_NAME = (uintptr_t) (CONST_NAME);
это было бы полезно. Но я не могу сделать это без этого ответа.
Спасибо!
Обновлять
Кто-то в IRC выразился по-другому (переформатировано, чтобы избежать горизонтальной прокрутки):
[19:13] <FraGag> basically, you're asking whether an int with a value of -1
will be returned as 0x00000000FFFFFFFF or as 0xFFFFFFFFFFFFFFFF
if an int is 4 bytes and an uintptr is 8 bytes
В основном это, но специально для взаимодействия с Windows API, для передаваемых параметров и независимо от размера uintptr.
InvalidHandle
как^Handle(0)
( аHandle
этоuintptr
). Итак, краткий ответ на мой эквивалентuintptr(-1)
—^uintptr(0)
(должен применяться в равной степени к 32- и 64-разрядным версиям). Если есть ситуации, когда вам нужно другое низкоуровневое приведение, которое Go не включает в язык, вы можете сделать это с помощью unsafe: play.golang.org/p/JObvq_X5x0 - person twotwotwo   schedule 04.06.2014uintptr
с помощью переноса, если вы объявите ихvar
вместоconst
и принудительно вычислите их. во время выполнения. Я думаю (размер uintptr) == (размер int) как на windows_386, так и на windows_amd64 (прямо для проверки!), Так что это не проблема. Вы также можете выполнить циклическую арифметику самостоятельно (даже в константах); этот ответ показывает, как. - person twotwotwo   schedule 04.06.2014