Управление памятью неуправляемого компонента с помощью CLR - PullRequest
9 голосов
/ 13 октября 2010

У меня небольшая путаница, может быть, этот вопрос очень глупый.

где память выделяется для неуправляемого компонента?

В моем .net-коде, если я инициировал неуправляемый компонент, куда этот компонент будет загружен и выделена память?

Как CLR выполняет вызов между управляемой и неуправляемой кучей?

РЕДАКТИРОВАТЬ

Спасибо за ваш ответ, но я спрашиваю, скажем, предположим, я делаю DLLIMPORT пользователя32.Функция в User32.DLL теперь мой вопрос, как CLR маршалл мой вызов этой неуправляемой DLL?

Ответы [ 4 ]

10 голосов
/ 13 октября 2010

Все начинается довольно просто.Маршаллер pinvoke сначала вызывает LoadLibrary и передает указанное имя DLL, свойство DllImportAttribute.Value.В вашем случае user32.dll уже загружен, потому что он загружается загрузчиком .NET, его счетчик ссылок просто увеличивается.Но обычно загрузчик Windows получает DLL, сопоставленную с адресным пространством процесса, чтобы можно было вызывать экспортированные функции.

Далее следует GetProcAddress, чтобы получить адрес вызываемой функции, свойство DllImportAttribute.EntryPoint.Маршаллер делает пару попыток, если вы не используете ExactSpelling.Имя функции типа "foo" проверяется несколькими возможными способами: foo и fooW или fooA.Неприятная деталь реализации Win32 связана с различием между символами Unicode и Ansi.Здесь имеет значение свойство CharSet.

Теперь мне нужно немного помахать руками, потому что это сложно.Маршаллер создает кадр стека, устанавливая аргументы, которые должны быть переданы в экспортируемую функцию.Для этого требуется код низкого уровня, тщательно исключенный из посторонних глаз.Принимайте во внимание, что он выполняет тот тип переводов, который поддерживает класс Marshal для преобразования между управляемым и неуправляемым типами.Здесь имеет значение свойство DllImportAttribute.CallingConvention, поскольку оно определяет, какое значение аргумента должно быть размещено там, чтобы вызываемая функция могла правильно его прочитать.

Затем он устанавливает обработчик исключений SEH, чтобы аппаратные исключения, вызванные вызываемым кодом, могли быть перехвачены и преобразованы в управляемое исключение.Тот, который генерирует более распространенный, AccessViolationException.И другие.

Затем он помещает специальный стек в стек, чтобы указать, что неуправляемый код собирается начать использовать стек.Это предотвращает грубую сборку мусора в кадрах неуправляемого стека и интерпретирует указатели, которые он там находит, как ссылки на управляемые объекты.Вы можете увидеть этот файл cookie в стеке вызовов отладчика [Managed to Native Transition].

Далее, просто косвенный вызов адреса функции, найденный с помощью GetProcAddress ().При этом запускается неуправляемый код.

После вызова может потребоваться очистка для освобождения памяти, выделенной для передачи неуправляемых аргументов.Возвращаемое значение может потребоваться преобразовать обратно в управляемое значение.И все, при условии, что ничего неприятного не произошло, выполнение продолжается при следующей инструкции управляемого кода.

8 голосов
/ 13 октября 2010

Неуправляемая память выделяется из кучи процесса. Вы несете ответственность за распределение / освобождение памяти, так как она не будет собирать мусор, потому что GC не знает об этих объектах.

1 голос
/ 22 августа 2012

Так же, как академическая информация, расширяющая то, что было размещено здесь:

Существует около 8 различных куч, которые использует CLR:

  1. Куча загрузчика:содержит структуры CLR и систему типов

  2. Высокочастотная куча: статика, MethodTables, FieldDescs, карта интерфейса

  3. Низкочастотная куча: EEClass, ClassLoaderи справочные таблицы

  4. Куча заглушек: заглушки для оболочек CAS, COM, P / Invoke

  5. Куча больших объектов: выделение памяти, требующее более85 Кбайт

  6. Куча GC: пользовательская память кучи, выделенная приложению

  7. Куча кода JIT: память, выделенная mscoreee (механизм выполнения) иJIT-компилятор для управляемого кода

  8. Process / Base Heap: взаимодействие / неуправляемые выделения, собственная память и т. д.

HTH

0 голосов
/ 13 октября 2010

На часть вашего вопроса ответил Михаил. Я отвечаю на другую часть.

Если CLR загружен в неуправляемый процесс, он называется CLR-хостингом. Обычно это включает в себя вызов точки входа в mscoree DLL, а затем загружается домен приложения по умолчанию. В таком случае CLR запрашивает блок памяти у процесса, и когда он передается, он становится пространством памяти и будет иметь стек и кучу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...