Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
 Аватар для Igor-84
28 / 27 / 11
Регистрация: 04.03.2010
Сообщений: 199

Нужен ли вызов FreeLibrary

01.05.2022, 23:51. Показов 1634. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Допустим, имеется некоторый класс MyClass, который использует функцию AlphaBlend(). Но условие - эта функция должна загружаться динамически.
Отсюда получается такой код:
C++
1
2
//прототип
typedef BOOL (WINAPI *LPFN_ALPHABLEND)(HDC, int, int, int, int, HDC, int, int, int, int, BLENDFUNCTION);
и сам класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class MyClass
{
public:
MyClass();
~MyClass();
void Draw();
 
private:
HMODULE MSIMG32_LIB;
};
 
MyClass::MyClass()
{
LPFN_ALPHABLEND fnAlphaBlend;
 
//если модуль загружен в процесс
MSIMG32_LIB = GetModuleHandle(TEXT("msimg32.dll"));
 
    if(!MSIMG32_LIB)
    {
    //если модуль не загружен в процесс
    MSIMG32_LIB = LoadLibrary(L"msimg32.dll");
    }
 
fnAlphaBlend = (LPFN_ALPHABLEND)GetProcAddress(MSIMG32_LIB, "AlphaBlend");
}
Метод Draw() и будет непосредственно вызывать функцию AlphaBlend().
Но так как в главном приложении создаётся два экземпляра этого класса, то появляется вопрос с вызовом функции FreeLibrary().

Здесь уже понятно, что в деструкторе класса MyClass не получится делать вызов FreeLibrary(), т.к. при удалении первого экземпляра класса, второй ещё может использовать импортированную функцию AlphaBlend().

Как можно здесь поступить правильно? Нужно ли вообще делать вызов FreeLibrary() в таком случае? Насколько правильным будет его не делать, а позволить главному приложению при завершении работы программы автоматически (без явного вызова FreeLibrary()) выполнить освобождение загруженной в процесс библиотеки?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.05.2022, 23:51
Ответы с готовыми решениями:

FreeLibrary очищает память которая выделялась в функции библиотеки?
Такой вот простой вопрос, по доке понятно что уменьшает счетчик и выгружает модуль.. А память-то? если внутри библиотеки выделили...

Непонятный код с FreeLibrary
static int open_gl(void) { libGL = LoadLibraryW(L"opengl32.dll"); if(libGL != NULL) { gladGetProcAddressPtr =...

Ошибка при вызове FreeLibrary
Здравствуйте! #include "pch.h" #include <iostream> #include <windows.h> HMODULE hDLL; int main() { hDLL =...

5
Эксперт С++
 Аватар для _lunar_
3701 / 2836 / 451
Регистрация: 03.05.2011
Сообщений: 5,193
Записей в блоге: 21
02.05.2022, 00:19
Цитата Сообщение от Igor-84 Посмотреть сообщение
Нужно ли вообще делать вызов FreeLibrary() в таком случае?
нужно, но когда - вам виднее.
вы же ваяете код, вот и смотрите когда библиотека больше не нужна.

я обычно выгружаю DLL в конце своей internal функции, т.к. повторный вызов этой функции снова загрузить эту DLL.
1
 Аватар для Igor-84
28 / 27 / 11
Регистрация: 04.03.2010
Сообщений: 199
02.05.2022, 00:56  [ТС]
Цитата Сообщение от _lunar_ Посмотреть сообщение
вот и смотрите когда библиотека больше не нужна
_lunar_, ну по логике, не нужна уже при вызове деструктора класса MyClass. Но всё было бы хорошо, если бы экземпляр класса был один, а их может быть несколько. И первый же вызов деструктора с освобождением библиотеки угробит жизнь остальным существующим экземплярам этого класса.
Цитата Сообщение от _lunar_ Посмотреть сообщение
я обычно выгружаю DLL в конце своей internal функции, т.к. повторный вызов этой функции снова загрузить эту DLL
Такой вариант неплох, если импортированная функция будет вызываться не часто. А в моём же случае используется графическая функция, количество вызовов которой может быть достаточно велико. И каждый раз при этом производить загрузку/выгрузку библиотеки как-то нерационально. Нужно что-то ещё придумать...
0
COM‐пропагандист
 Аватар для Замабувараев
936 / 785 / 149
Регистрация: 18.12.2014
Сообщений: 2,256
Записей в блоге: 4
02.05.2022, 06:51
Цитата Сообщение от Igor-84 Посмотреть сообщение
Нужно ли вообще делать вызов FreeLibrary() в таком случае?
Когда ваш процесс будет завершён, то система в любом случае автоматически выгрузит из памяти все библиотеки которые вы загружали.
Цитата Сообщение от Igor-84 Посмотреть сообщение
не нужна уже при вызове деструктора класса MyClass
Если вы хотите выгружать библиотеку из памяти вручную, то заведите счётчик ссылок на библиотеку. Конструктор объекта будет увеличивать счётчик, деструктор объекта будет уменьшать этот счётчик. Когда счётчик станет равным нулю, это значит, что на библиотеку ссылается никто, следовательно, библиотеку больше не нужна в памяти и можно выгружать.
0
2650 / 1661 / 267
Регистрация: 19.02.2010
Сообщений: 4,394
02.05.2022, 09:50
Цитата Сообщение от Igor-84 Посмотреть сообщение
Но всё было бы хорошо, если бы экземпляр класса был один, а их может быть несколько.
Так классический ведь паттерн проектирования - https://ru.wikipedia.org/wiki/... ктирования)
Т.е. перенеси поле-дескриптор из своего класса в отдельный класс-singleton. И поле-указатель на функцию туда же упихай, чтобы отдавать из синглтона именно готовый указатель на функцию (вместо дескриптора либы).
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
02.05.2022, 13:36
Цитата Сообщение от Igor-84 Посмотреть сообщение
Но так как в главном приложении создаётся два экземпляра этого класса, то появляется вопрос с вызовом функции FreeLibrary().
Здесь уже понятно, что в деструкторе класса MyClass не получится делать вызов FreeLibrary(), т.к. при удалении первого экземпляра класса, второй ещё может использовать импортированную функцию AlphaBlend().
Здесь классическая ошибка смешивания ответственности.
Отсюда и все эти проблемы.
Почему вообще MyClass занимается загрузкой библиотеки, да еще и 2 раза, с учетом того, что вы создаете два экземпляра?
Как только вы разделите ответственность загрузки библиотеки и использования результата этой загрузки (например, как выше предложили с помощью singleton, либо просто в отдельном классе-загрузчике, объект которого создается до ваших объектов MyClass - здесь уже как угодно), то все сразу станет гораздо более управляемым.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.05.2022, 13:36
Помогаю со студенческими работами здесь

Принцип работы функции FreeLibrary()
Учусь работать с DLL библиотеками, которые сам делаю в DELPHI 7. Проблема в следующем: Я динамически вызываю из главной формы по...

application-defined exception. Ошибка в FreeLibrary
Всем привет. Прошу помощи у вас, потому что второй день не могу понять в чем проблема! Имеется *.dll и MDI приложение. В *.dll...

Зачем в программе нужен вызов setlocale?
Смотрел видеоурок по теме switch.Парень работал в Vusial Studio.После int main() у него стоит setlocale(LC_ALL,"ru"); Что это...

Нужен пример на OleDb - заполнение ДатаГрида через вызов хранимой процедуры с параметрами. (ASP.NET)
Процедура CREATE PROCEDURE pr_GetClient @pID_Customer INT, @pName varchar(30), @pZip varchar(6) With Recompile AS ...

Вызов методов классов друг у друга (вызов метода из другого класса)
Есть несколько классов, которые могут вызывать методы (функции) друг у друга. Логика: класс1 имеет метод А, класс2 имеет метод Б, класс1...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru