![]() |
|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
![]() |
|
|
Опции темы | Поиск в этой теме |
![]() |
#1 |
Eclipse Foundation
Старожил
Регистрация: 19.09.2007
Сообщений: 2,604
|
![]()
Тема не очень сложная, но при этом очень важная. В этой теме я расскажу как создавать DLL и загружать ее в проект двумя способами - статически и динамически.
Итак, начнем с создания. Используется Microsoft Visual Studio 2005 File->New->Project->Win32 Project, затем вписываем имя, я назову свою DLL просто - MyDLL. Затем нажимаем ОК. В появившемся окне щелкаем на кнопку Next. Ставим галочку напротив DLL. Поля ATL и MFC оставляем пустыми. Empty project тоже нужно поставить галочку. Будем писать все с нуля. Нажимаем Finish. Теперь нам нужно добавить в проект *.cpp файл с исходным кодом. Правой кнопкой по папке Source Files в Solution Explorer ->New Item... Выбираем cpp-файл, я дал ему имя Source.cpp. Теперь допишем сюда нашу функцию. Моя функция будет считать количество вхождений символа в строку, и возвращать значение типа int. Но сначала добавим в этот проект еще один файл - MyDll.h, и скопируем туда вот этот код Код:
extern "C" _declspec(dllexport) - это означает, что моя функция будет экспортироваться в ехе файл программы. Дальше пишем реализацию в файл Source.cpp Итак, готовый код Код:
Наша DLL готова. Следующий пост я напишу как загрузить мою функцию из DLL в проект. |
![]() |
![]() |
![]() |
#2 |
Eclipse Foundation
Старожил
Регистрация: 19.09.2007
Сообщений: 2,604
|
![]()
Итак, как загрузить DLL в программу. Существует два способа - статически и динамически. Первый загружает DLL в память на этапе компиляции, а второй - на этапе выполнения программы.
1)Статическое подключение Когда мы слинковали нашу DLL, мы получили 3 файла. 1. MyDll.dll 2. MyDll.lib 3. MyDll.exp Первый файл - собственно DLL. Второй - таблица импорта. Третий - таблица экспорта. Чтобы подключить статически DLL к программе, нам нужно: 1. Подключить h-файл этой DLL к нашей программе (если такого файла нет, то подключать ничего не нужно ![]() 2. Подключить lib-файл к нашей программе. В нашем случае нужно написать две строки в самом начале программы (после инклудов) Код:
Все, дальше можно вызывать эту функцию как обычную функцию. Для примера привожу готовый код программы, которая импортирует функцию из DLL. На WinApi File->New->Project->Win32 Project->Windows Application->Empty Project->Finish Source Files->New Item->Main.cpp Код:
|
![]() |
![]() |
![]() |
#3 |
Eclipse Foundation
Старожил
Регистрация: 19.09.2007
Сообщений: 2,604
|
![]()
2)Динамическое подключение
Чтобы загрузить DLL в программу на этапе выполнения, нужно пройти несколько шагов. Шаг 1: Использовать функцию LoadLibrary или LoadLibraryEx, чтобы загрузить DLL. Шаг 2: Использовать функцию GetProcAddress, чтобы получить указатель на интересующую нас функцию. Шаг 3: По окончании работы не забыть выгрузить DLL с помощью функции FreeLibrary. В своей программе я пользовался функцией LoadLibraryEx, потому что у нее есть параметр, который определяет, каким образом загружать DLL. Эта функция возвращает дескриптор DLL. Код:
Дальше - нам нужно получить указатель на функцию. Но функция у нас не простая, а с кучей параметров. Тоесть нужно определить тип указателя. Это делается строкой (в нашем случае) Код:
Далее - дело за малым. Код:
Первый параметр - дескриптор DLL. Второй - имя функции. Теперь можно вызывать эту функцию с параметрами Код:
File->New->Project->Win32 Project->Windows Application->Empty project. Source files->New Item->Main.cpp Код:
Последний раз редактировалось MaTBeu; 11.01.2010 в 15:24. |
![]() |
![]() |
![]() |
#4 |
Старожил
Регистрация: 06.08.2009
Сообщений: 2,992
|
![]()
Когда я писал свой DLL и подключал его через LoadLibrary(), то я не мог обратиться к функции (через GetProcAddress) по имени - можно было только по номеру (а тот вообще был случайный). Проблема решилась добавлением в проект DLL файла .def примерно следущего содержания:
Код:
В коде программы, использующей DLL, объявление функции можно записать проще, типа: void (*SetValue)(double) = (void(*)(double)) GetProcAddress (LibInst, "SetValue"); А потом вызывать, например, SetValue (1.25); А еще можно все это занести в какую-нибудь функцию InitDLL() в *.h файл, который будет распространяться с вашим DLL. Тогда человеку, который будет ее использовать будет нужно добавить этот заголовочный файл и вызвать InitDLL(), и ему будут доступны все эти функции. |
![]() |
![]() |
![]() |
#5 |
Старожил
Регистрация: 06.08.2009
Сообщений: 2,992
|
![]()
Вот мой Starter Kit, демонстрирующий DLL.
Project DLL: DLL.cpp (исходный код библиотеки): Код:
Код:
Project DLLUse: DLLUse.h (поставляется автором вместе с его *.dll Код:
Код:
Кстати, кто-нибудь знает, есть ли в Standart C++ (где-нибудь в <iostream>) альтернатива функции getch()? P. S. Извините, но у меня размер таба - 4 символа. ![]() Модератор: за информацию спасибо. Альтернатива getch() есть, cin.get() Последний раз редактировалось MaTBeu; 10.08.2009 в 15:13. |
![]() |
![]() |
![]() |
#6 |
Старожил
Регистрация: 28.01.2009
Сообщений: 21,000
|
![]()
у меня вопрос по статическому подключению.
а как мне статически подключить чужую ДЛЛ? (к которой у меня нет lib файла) Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел. Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите. |
![]() |
![]() |
![]() |
#7 |
Участник клуба
Регистрация: 18.10.2008
Сообщений: 1,409
|
![]() |
![]() |
![]() |
![]() |
#8 |
Форумчанин
Регистрация: 28.01.2010
Сообщений: 224
|
![]()
я по вопросу динамического присоединения а возможно попроше например (но я не уверен, если неверно то поясни!!!)
Загрузка библиотеки с помощью функции LoadLibrary: HIHSTANCE diiInstance = LoadLibrary (“название необходимой dll"); Получим указатель на интересующую функцию. typedef char (_import *FType (char*));//вводим тип FType (произвольное имя). При //объявлении указывается тип возвращаемого значения. FType *MyFunc; // задает тип указателя на функцию MyFunc = (FType*) GetProcAddres (diiInstance, “_MyFunction “);// для получения //значения этого указателя. // тогда вызов функции из библиотеки: char* S = MyFunc (“Привет вам”); // выгрузить библиотеку из памяти необходимо по окончании работы с ней. FreeLibrary (diiInstance); В данном примере вызываемая функция char* MyFunction (char*)
всему свое время как зиме и весне
и каждому солнцу свой неба кусок Последний раз редактировалось Assemblerru; 03.02.2010 в 19:26. |
![]() |
![]() |
![]() |
#9 |
Eclipse Foundation
Старожил
Регистрация: 19.09.2007
Сообщений: 2,604
|
![]()
Я уже отвечал - она так и подключается - остальной код - это графический интерфейс.
|
![]() |
![]() |
![]() |
#10 |
Форумчанин
Регистрация: 28.01.2010
Сообщений: 224
|
![]()
прости сразу не разобрался я на работе почитал и все в принцепе понятно. А ты не рботал с inpout32.dll. Где можно описания найти для динамического подключения ее к проекту (покрайней мере какие функции и с какими параметрами). Покрайней мере я ее хочу использовать для работы с портами ввода вывода. На форумах пообщался нащел только такое:
http://azbukavb.narod.ru/teorie/LPT.html
всему свое время как зиме и весне
и каждому солнцу свой неба кусок |
![]() |
![]() |
![]() |
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Вопрос по Microsoft Visual C++ | DiZZZ | Visual C++ | 3 | 06.04.2009 18:45 |
Microsoft Visual C++ 6.0 | saleens7 | Помощь студентам | 6 | 26.12.2008 16:16 |
Работа с окнами в Microsoft Visual Studio 2005 | M@STeR | Visual C++ | 1 | 24.09.2008 14:44 |
Delphi и Microsoft Visual Basic | Dimon88 | Общие вопросы Delphi | 10 | 23.11.2007 14:46 |
Visual J# from Microsoft Visual Studio .NET | Flash_ | Общие вопросы по Java, Java SE, Kotlin | 2 | 28.12.2006 10:16 |