Некоторые предположения: (поправьте меня, если не прав)
Игнорируя 16-битные данные, VBA может работать на 32- или 64-битных хостах Office. 64-разрядную версию Office можно запускать только в 64-разрядной ОС, тогда как 32-разрядную версию Office можно запускать в 64-разрядной версии Windows / macOS или другой операционной системы 32 или .
Начиная с VBA7, у нас есть тип LongPtr
, который становится Long
в 32-битном Office (#Win64 = False
), LongLong
в 64-битном Office (#Win64 = True
), независимо битность ОС
Мой вопрос: В API, которые имеют дело с указателями (адресами в памяти), имеет ли значение разрядность ОС или это только приложение, выполняющее код, который нас интересует (32 / 64-битный хост Office / VBA)?
Текущее понимание:
С одной стороны, я понимаю, почему это может не иметь значения:
- VBA, работающая в 32-битном Excel, будет иметь 32-битное адресное пространство (независимо от ОС)
- Следовательно, любые указатели на собственную память должны быть 32-разрядными (т. Е.
Long
s - LongPtr
дает нам это)
- Аналогично, 64-битный VBA (обязательно в 64-битной ОС, но действительно может быть где угодно) имеет 64-битное адресное пространство (каждый указатель имеет длину 64 бита и относится к блоку памяти шириной 64 бита)
- Поэтому любые указатели на собственную память должны быть 64-битными (т. Е.
LongLong
s - LongPtr
дает нам это)
- Итак,
LongPtr
точно представляет указатель на собственную память моего кода, независимо от разрядности ОС
Однако я могу представить времена, когда битность ОС могла бы иметь значение
- Запуск 32-разрядного VBA в 64-разрядной ОС, но при обращении к областям в памяти другого 64-разрядного приложения тип
LongPtr
оценивается как Long
и будет слишком коротким, чтобы представлять максимум Размер указателя доступен в этой ОС.
- Точно так же 64-разрядный VBA, обращающийся к памяти 32-разрядного приложения, обнаружил бы, что его тип указателя слишком велик для хранения адреса
- Теперь пользующийся доверием тип
LongPtr
на самом деле имеет неправильную длину для представления указателя на адрес в памяти вне собственного адресного пространства VBA!
Проблемы могут теперь возникать в зависимости от разрядности ОС, а не от разрядности Office / VBA. Если мы запускаем VBA7 в 32-битной ОС, тогда LongPtr
будет правильной длиной для любого куска памяти, который вы захотите использовать; это подходящий тип данных указателя в 99,9% случаев, поскольку все, что делает ОС, является 32-разрядным (игнорируя 16-разрядное).
Однако тот же 32-битный код VBA7, который выполняется вместо 64-битной ОС, может столкнуться с трудностями при попытке использовать LongPtr
для хранения 32-битных адресов. Я чувствую, что довольно часто смешивать 32-битные и 64-битные приложения в 64-битной ОС, так что это может быть реальной проблемой.
32-разрядные VBA6 и более ранние приложения, работающие в 32-разрядных и 64-разрядных операционных системах, могут сталкиваться с аналогичными проблемами, только без помощи LongPtr
Теперь я понимаю, что это довольно надуманная ситуация, кто захочет получить доступ к памяти другого приложения, верно? На самом деле это настолько изобретательно, что я не уверен, что смогу когда-нибудь придумать ситуацию, в которой это важно и о чем стоит беспокоиться. Может ли приложение когда-либо получить адрес в памяти другого приложения с другой разрядностью? Может быть, есть некоторые средства защиты от чтения и записи, предотвращающие это.
Возможно, доступ к дескриптору окна другого приложения был бы одним из таких случаев; это общедоступная память, и, возможно, разрядность дескриптора окна отражает разрядность приложения или операционной системы, и в этом случае мой 32-разрядный VBA мог бы содержать ссылку на 64-разрядную Hwnd
, Я не уверен ...
PS Я знаю, что существуют ситуации, отличающиеся от длины указателя, где битность ОС может быть важной. Я знаю одного; функция SetWindowLong
требовала разных объявлений в 64-битной и 32-битной Windows - хотя IIUC теперь была решена с помощью функции SetWindowLongPtr
, которая идентична для обеих. Но о любых других подобных причудах было бы полезно знать, я только фокусируюсь на длине указателя, потому что у меня есть проблема, которая требует конкретной информации.
PPS приходит к выводу, можете ли вы даже получить битность ОС во время компиляции; Я думаю, что вы можете сделать вывод из MAC_OFFICE_VERSION
, а ofc Win64 = True
означает 64-битную версию Office и де-факто 64-битную ОС. Но я не уверен, есть ли способ узнать, работает ли 32-битный VBA в 64-битной Windows ...