Вызов функций в DLL из C++
-
22-08-2019 - |
Вопрос
У меня есть решение в VS 2008 с двумя проектами.Одна из них — это DLL, написанная на C++, а другая — простое консольное приложение C++, созданное на основе пустого проекта.Я хотел бы знать, как вызывать функции DLL из приложения.
Предположим, я начинаю с пустого проекта C++ и хочу вызвать функцию с именем int IsolatedFunction(int someParam)
Как мне это назвать?
Решение
Есть много способов сделать это, но я думаю, что один из самых простых вариантов — связать приложение с DLL во время компоновки, а затем использовать файл определения чтобы определить символы, которые будут экспортированы из DLL.
ПРЕДОСТЕРЕЖЕНИЕ: Подход с использованием файла определений лучше всего подходит для не украшенный названия символов.Если вы хотите экспортировать декорированные символы, возможно, лучше НЕ ИСПОЛЬЗОВАТЬ подход к файлу определений.
Вот простой пример того, как это делается.
Шаг 1: Определите функцию в экспорт.ч файл.
int WINAPI IsolatedFunction(const char *title, const char *test);
Шаг 2: Определите функцию в экспорт.cpp файл.
#include <windows.h>
int WINAPI IsolatedFunction(const char *title, const char *test)
{
MessageBox(0, title, test, MB_OK);
return 1;
}
Шаг 3: Определите функцию как экспорт в экспорт.def файл определения.
EXPORTS IsolatedFunction @1
Шаг 4: Создайте проект DLL и добавьте экспорт.cpp и экспорт.def файлы в этот проект.Создание этого проекта создаст экспорт.dll и экспорт.lib файл.
Следующие два шага связаны с DLL во время компоновки.Если вы не хотите определять точки входа во время компоновки, проигнорируйте следующие два шага и используйте команду Загрузить библиотеку и GetProcAddress для загрузки точки входа функции во время выполнения.
Шаг 5: Создать Тест проект приложения для использования dll, добавив экспорт.lib файл в проект.Скопируйте экспорт.dll файл в то же место, где находится Тест консольный исполняемый файл.
Шаг 6: Позвоните в ИзолированнаяФункция функцию из тестового приложения, как показано ниже.
#include "stdafx.h"
// get the function prototype of the imported function
#include "../export/export.h"
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// call the imported function found in the dll
int result = IsolatedFunction("hello", "world");
return 0;
}
Другие советы
Также можно экспортировать функции из dll и импортировать из exe, поначалу это сложнее, но в конечном итоге намного проще, чем вызов LoadLibrary/GetProcAddress.Видеть MSDN.
При создании проекта с помощью мастера VS в dll есть флажок, позволяющий экспортировать функции.
Затем в приложении exe вам нужно только #include заголовок из dll с соответствующими определениями и добавить проект dll в качестве зависимости к приложению exe.
Проверьте этот другой вопрос, если вы хотите изучить этот вопрос дальше. Экспорт функций из DLL с помощью dllexport.
Вы можете либо пойти по маршруту LoadLibrary/GetProcAddress (как упомянул Харпер в своем ответе, вот ссылка на Пример динамического связывания во время выполнения MSDN или вы можете связать свое консольное приложение с .lib, созданным из проекта DLL, и включить файл hea.h в объявление вашей функции (как описано в Пример MSDN динамического связывания во время загрузки)
В обоих случаях вам необходимо убедиться, что ваша DLL правильно экспортирует функцию, которую вы хотите вызвать.Самый простой способ сделать это — использовать __declspec(dllexport) в объявлении функции (как показано в примере создания простой пример библиотеки динамической компоновки MSDN), хотя вы также можете сделать это через соответствующий файл .def в вашем проекте DLL.
Для получения дополнительной информации по теме DLL вам следует просмотреть MSDN о библиотеках динамической компоновки тема.
Необходимо выполнить следующие 5 шагов:
- объявить указатель на функцию
- Загрузите библиотеку
- Получить адрес процедуры
- присвойте его указателю на функцию
- вызвать функцию, используя указатель на функцию
Вы можете найти пошаговый снимок экрана VC++ IDE по адресу http://www.softwareandfinance.com/Visual_CPP/DLLDynamicBinding.html
Вот фрагмент кода:
int main()
{
/***
__declspec(dllimport) bool GetWelcomeMessage(char *buf, int len); // used for static binding
***/
typedef bool (*GW)(char *buf, int len);
HMODULE hModule = LoadLibrary(TEXT("TestServer.DLL"));
GW GetWelcomeMessage = (GW) GetProcAddress(hModule, "GetWelcomeMessage");
char buf[128];
if(GetWelcomeMessage(buf, 128) == true)
std::cout << buf;
return 0;
}
Предполагая, что вы говорите о динамической загрузке DLL во время выполнения, вам нужны LoadLibrary и GetProAddress.Есть пример на MSDN.
При создании DLL обычно автоматически создается библиотека импорта, и вам следует использовать ее, связанную с вашей программой, вместе с файлами заголовков для ее вызова, но если нет, вы можете вручную вызвать функции Windows, такие как Загрузить библиотеку и GetProcAddress чтобы заставить его работать.