Форум С++

 

Ответить на сообщение

Вернуться к теме

Вы отвечаете на сообщение:

Автор: cheops   (28.01.2012 в 10:09)
В общем да, в имеется две стратегии: связывание на этапе построения, когда вы добавляете DLL-библиотеку в проект или динамическое связывание во время работы программы. Именно для последнего случая предназначена LoadLibrary(), да собственно и сами DLL-библиотеки. Там не то чтобы сложно - "этикету" больше, но если один раз разобраться - потом не "страшно" :)))
Я так понимаю, с созданием DLL-библиотеки проблем не возникает? На всякий случай я приведу код простейшей библиотеки с одной функцией, HelloWorld(), которая этот самый "Hellow world" и выводит.
#include <Windows.h>
#include <iostream>
using namespace std;

// Главная функция
BOOL WINAPI DllMain(HINSTANCE hDll, DWORD dwReason, LPVOID lpReserved)
{
  switch(dwReason)
  {
    case DLL_PROCESS_ATTACH:
      break;
    case DLL_THREAD_ATTACH:
      break;
    case DLL_THREAD_DETACH:
      break;
    case DLL_PROCESS_DETACH:
      break;
  }
  return TRUE;
}

extern "C" __declspec(dllexport) void HelloWorld(void)
{
  cout << "Hello world" << endl;
}
Главная функция DllMain() практически пустая, события не обрабатываются, нам не надо, так как у нас нет никакой динамической памяти, параллельных потоков и прочего. Теоретически можно вообще DllMain() не создавать - она должна добавляться автоматически компилятором. Функция HelloWorld() объявлена без параметров и возвращаемых результатов, но можно и с тем и с другим - никаких сложностей не возникает. Чтобы функцию было "видно" из вне, она объявляется с атрибутами extern и __declspec(dllexport), "C" - это порядок чтения аргументов, у нас тут их вообще нет, но приводим для единообразия.

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

При условии, что DLL-проект называется dll, а библиотека на выходе соответственно dll.dll, консольный проверочный проект может выглядеть следующим образом
#include <Windows.h>
#include <iostream>
#include <tchar.h>
using namespace std;

int main()
{
  // Дескриптор DLL-библиотеки
  HMODULE hDll;
  // Указатель на функцию
  void (*dllHelloWorld) (void);

  // Загружаем динамически подключаемую библиотеку
  hDll = LoadLibrary(_T("dll.dll"));
  if(!hDll)
  {
    cout << _T("Динамическая библиотека не загружена") << endl;
    return GetLastError();
  }
  // Настраиваем адрес функции
  dllHelloWorld = (void (*)(void))GetProcAddress(hDll, "HelloWorld");
  if(!dllHelloWorld)
  {
    cout << _T("Ошибка получения адреса функции") << endl;
    return GetLastError();
  }
  // Вызываем функцию из библиотеки
  dllHelloWorld();

  // Отключаем библиотеку
  if(!FreeLibrary(hDll))
  {
    cout << _T("Ошибка выгрузки библиотеки из памяти") << endl;
    return GetLastError();
  }
  
  // Устанавливаем паузу перед завершением программы
  system("pause");
  return 0;
}
PS Все проекты в UNICODE, т.е. строки обрамляем макросом _T, если программе нужны параметры, вместо main() используем _tmain(). Кстати, обратите внимание, что GetProcAddress() принимает обычные 8-битные строки, поэтому если у вас названия функций в LPTSTR/LPCTSTR-строках, придется переводить.


Ваше имя:

Пароль:

Цитировать

Используйте тэги для выделения текста:
Код: [code][/code]
Жирный: [b][/b]
Наклонный: [i][/i]
URL: [url][/url]

Сообщение:

Прикрепить: