Dll Управление памятью - PullRequest
       5

Dll Управление памятью

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

У меня мало сомнений относительно того, как windows управляет памятью .dll.

  • когда .dll загружаются в хост процесс, как управляется память?

  • .dll получает доступ ко всему доступная память для хост-процесса или только часть? то есть есть ограничение, когда память распределяется функцией внутри .dll

  • Будут ли STL классы, такие как строка, вектор (динамически увеличение хранилища) и т. д., используемые dll, здесь можно работать без проблем?

Ответы [ 2 ]

5 голосов
/ 27 октября 2010

«Управление памятью», как правило, является разделенной ответственностью. ОС передает адресное пространство большими кусками во время выполнения, которое затем передает его меньшими битами программе. Это адресное пространство может иметь или не иметь выделенную оперативную память. (Если нет, там будет место подкачки, чтобы поддержать его)

Обычно, когда загружается DLL, Windows выделяет адресное пространство для кода и сегментов данных и вызывает DllMain(). Компилятор C ++ организует вызов глобальных ctors из DllMain(). Если это DLL, написанная на C ++, она, вероятно, будет зависеть от DLL времени выполнения C ++, которая, в свою очередь, будет зависеть от Kernel32.DLL и User32.DLL. Windows понимает такие зависимости и организует их загрузку в правильном порядке.

Существует только одно адресное пространство для проверки, поэтому DLL получит доступ ко всей памяти процесса. Если DLL загружена в двух процессах, будет две логические копии кода и данных. (хотя копии кода и данные только для чтения могут использовать одну и ту же физическую память).

Если DLL выделяет память с помощью функций ОС, Windows выделяет память для процесса, из которого DLL произвела это выделение. Процесс должен вернуть память, но любой код в процессе может это сделать. Если ваша DLL выделяет память с помощью функций C ++, она будет делать это, вызывая operator new в DLL времени выполнения C ++. Эта память должна быть возвращена путем вызова operator delete в (той же самой) C ++ DLL времени выполнения. Опять же, не имеет значения, кто это делает.

Классы STL, такие как vector<>, могут быть многократно созданы, но это не имеет значения, если вы используете один и тот же компилятор. Все экземпляры будут по существу равны, и все вернут память вектора к одной и той же функции освобождения.

В этом объяснении есть 2 основных предположения:

  1. EXE и его библиотеки DLL скомпилированы одним и тем же компилятором
  2. Все EXE-файлы и их библиотеки DLL связаны с динамической библиотекой C ++ (то есть статически не связаны)

Статическое связывание со средой выполнения C ++ полезно, если вы хотите загрузить один автономный EXE-файл. Но если вы уже отправляете библиотеки DLL, вы должны также сохранить среду выполнения C ++ в своей собственной библиотеке DLL.

5 голосов
/ 27 октября 2010

.dll получает доступ ко всему доступная память для хост-процесса или только часть? то есть ограничение при выделении памяти функцией внутри .dll?

После того, как DLL была загружена в хост-процесс, нет никакого различия для кода"живущего" в DLL и кода "живущего" в исходном исполняемом модуле. Для выполняемого процесса все диапазоны памяти одинаковы, независимо от того, взяты они из DLL или из исходного исполняемого файла.

Нет никаких различий в отношении того, что может делать код из библиотеки DLL, и того, что может делать код, скомпилированный в исходном модуле exec.

Тем не менее, это различия при использовании кучи - это объясняется в вопросах, которые Space_C0wb0y предоставил ссылки в комментариях

Будут ли классы STL как строка, вектор (динамически увеличивающееся хранилище) и т. д. используется dll, работает без проблем здесь

Они будут создавать проблемы (решаемые, но все же), если вы используете их в интерфейсе вашей DLL. не будет (или только в очень редких случаях) создавать проблемы, если вы не используете их на уровне интерфейса DLL. Я уверен, что есть несколько более конкретных вопросов + ответы для этого.

По сути, если вы используете их на уровне интерфейса, DLL и EXE должны быть скомпилированы с "точно" одинаковыми флагами, то есть типы должны быть двоично-совместимыми. То есть если флаги компилятора (оптимизация и т. д.) в вашей DLL отличаются от тех, что в EXE, так что std::string по-разному размещается в памяти в EXE и DLL, тогда передача строкового объекта между ними приведет к в аварии или молчаливой ошибке (или демоны вылетают из носа).

Если вы используете только типы STL внутри функций или между функциями, внутренними для вашей DLL, то их совместимость с EXE не имеет значения.

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