GetProcAdress против линкера

Проведя некоторые исследования по связыванию DLL, я натолкнулся на два разных способа загрузки DLL.

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

Второй метод использовал GetProcAdress, который объявлен в заголовке windows.h. Это было сделано путем создания HINSTANCE и установки его с помощью LoadLibrary ("mylib.dll") (или любого другого имени библиотеки DLL, которое я связываю) и установки функциональной точки по адресу GetProcAdress (hInstance, "myFunction").

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

Спасибо!

3 ответа

Есть плюсы / минусы для обоих методов. Первый может использоваться для экспорта / импорта классов C++. Трудно сделать то же самое, используя LoadLibrary/GetProcAddress().

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

Оба метода используются довольно широко, и оба достаточно быстры, чтобы пренебречь их скоростью.

Первый метод, "через компоновщик", загружает и связывает DLL при запуске программы. Если DLL отсутствует, программа не запустится, и вы не сможете контролировать это поведение: именно так ОС загружает исполняемые файлы. Я бы сказал, что он используется чаще, потому что его проще использовать. Вы просто добавляете файл библиотеки и больше ни о чем не беспокоитесь, все просто работает.

Второй метод, с LoadLibrary, дает вам контроль над тем, когда и как вы загружаете библиотеки DLL; это позволяет вам выгружать и перезагружать библиотеки DLL во время работы программы, и ваша программа может обрабатывать отсутствующие библиотеки DLL указанным вами способом. Но это требует больше усилий (написание всех этих LoadLibrary а также GetProcAddress звонки).

Какая практика программирования лучше, зависит от того, как (и почему) вы используете библиотеки DLL. Первый способ охватывает большинство случаев.

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

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

Другие вопросы по тегам