Вы уже знаете, что глобальные
Вы уже знаете, что глобальные и статические переменные ЕХЕ-файла пе разделяются его параллельно выполняемыми экземплярами. В Windows 98 это достигается за счет выделения специальной области памяти для таких переменных при проецировании ЕХЕ-файла на адресное пространство процесса, а в Windows 2000 — с помощью механизма копирования при записи, рассмотренного в главе 13 Глобальные и статические переменные DLL обрабатываются точно так же. Когда какой-то процесс проецирует образ DLL-файла на свое адресное пространство, система создает также экземпляры глобальных и статических переменных.
NOTE:
Важно понимать, что единое адресное пространство состоит из одного исполняемого модуля и нескольких DLL-модулей. Одни из них могут быть скомпонованы со статически подключаемой библиотекой С/С++, другие — с DLL-версией той же библиотеки, а третьи (написанные нс на С/С++) вообще ею не пользуются Многие разработчики допускают ошибку, забывая, что в одном адресном пространстве может одновременно находиться несколько библиотек С/С++. Взгляните на этот код:
VOID EXEFunc()
{
PVOID pv = DLLFunc();
// обращаемся к памяти, на которую указывает pv;
// предполагаем, что pv находится в С/С++-куче ЕХЕ-файла
free(pv);
}
PVOID DLLFunc()
{
// выделяем блок в С/С++-куче DLL return(malloo(100));
}
Ну и что Вы думаете? Будет ли этот код правильно работать? Освободит ли ЕХЕ-функция блок, выделенный DLL-функцией? Ответы на все вопросы одинаковы- может быть Для точных ответов информации слишком мало. Если оба модуля (EXE и DLL) скомпонованы с DLL-версией библиотеки С/С++, код будет работать совершенно нормально. По ссли хотя бы один из модулей связан со статической библиотекой С/С++, вызов free окажется неудачным. Я нс раз видел, как разработчики обжигались на подобном коде.
На самом деле проблема, решается очень просто, ссли в модуле есть функция, выделяющая память, в нем обязательно должна быть и противоположная функция, которая освобождает память. Давайте-ка перепишем предыдущий код так:
VOID EXEFunc()
{
PVOID pv = DLLFunc();
// обращаемся к памяти, на которую указывает pv, // не делаем никаких предположений по поводу С/С++-кучи DLLFreeFunc(pv);
}
PVOID DllLFunc()
{
// выделяем блок в С/С++-кую DLL
PVOID pv = malloc(100); return(pv);
}
BOOL DLLFreeFunc(PVOID pv)
{
// освобождаем блок, выделенный в С/С++-куче OLL
return(free(pv));
}
Этот код будет работать при любых обстоятельствах Создавая свой модуль, не забывайте, что функции других модулей могут быть написаны па других языках, а значит, и ничего нс знать о malloc и free. Не стройте свой код на подобных допущениях. Кстати, то же относится и к С++-опсраторам new и delete, реализованным с использованием malloc frее
Содержание Назад Вперед
Forekc.ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий