Насколько я могу судить, все это относится к объектам в куче ГХ.
Дело в том, что я имею в виду именно память STACK.
Я опубликовал пример, который, по-видимому, предполагает, что стековая память повреждена во время передачи вызова стека API в виде буфера:
http://social.msdn.microsoft.com/Forums/en-US/clr/thread/3779c1ee-90b8-4a6a-9b14-f48d709cb27c
Если стековая память должна быть закреплена, то это, похоже, нарушает идею «Это просто работает». В неуправляемом C ++ мы можем объявить буфер стека и затем передать указатель на него в функцию API. Однако, если переход к управляемому коду требует закрепления, это может подорвать «Это просто работает».
Это сбивает с толку то, как документы MSDN для pin_ptr говорят, что они предназначены только для предотвращения перемещения объектов, однако также возможно закрепить типы значений, которые, по-видимому, находятся в стеке и не должны двигаться в любом случае.
Я специально поднимаю вопрос о том, как стековая память обрабатывается одинаково в управляемом или неуправляемом коде. При отладке MSIL я обнаружил, что просмотр стека невозможен, и для этого нет средства просмотра стека. Я слышал, но не уверен, что в MSIL нет «реального» стека, и вместо этого CLR виртуальной машины можно оптимизировать, например, используя свободные регистры процессора вместо реальной памяти. Неясно, верно ли это, и применимо ли это к стеку, как при передаче параметров, или к стеку, как в локальной переменной памяти.
Странный эффект в приведенном выше примере проекта заключается в том, что pin_ptr на разрушающем объекте, похоже, решает проблему. однако объект находится на СТЕКЕ и не нуждается в закреплении. Может быть так, что / CLR интерпретирует pin_ptr как не только «не перемещать этот объект», но также «покидать эту область как истинную память и не пытаться зарегистрировать оптимизации для нее», что приведет к тому, что она останется чистой на время вывода
Мне бы особенно хотелось узнать, достаточно ли умен / CLR, чтобы избежать оптимизации памяти стека в методе во время вызова API, но, возможно, не даст мне такую же грацию в приведенном выше примере из-за прямая загрузка NTDLL и способ объявления функции как typedef.
Я рассмотрел добавление атрибутов Marshalling в функцию typedef, но, похоже, не смог этого сделать. Хочу заметить, что в определениях WinAPI нет атрибутов MarshallAs.
Мне удалось проникнуть в проект выше с помощью __debugbreak () непосредственно перед вызовом NTDLL, однако это только дает мне режим управляемой отладки, который кажется неспособным войти в нативный код. Я не могу написать «asm int 3», потому что x64 не поддерживает его. Однако я вижу, что ошибочное значение NumberOfPairs передается в ячейку памяти, на которую указывает регистр, а не как сам регистр.