КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Динамически подключаемые библиотеки (примеры)
Работа с классами при явной загрузке DLL
1-й вариант. Доступ к методам класса через их порядковые номера В тех случаях, когда с помощью.def файла или секции экспорта DLL, можно определить порядковые номера всех методов класса в библиотеке, в приложении необходимо предусмотреть следующее: - получение адресов конструктора, деструктора и не виртуальных методов класса в DLL можно выполнять с помощью функции GetProcAddress() через их порядковые номера; - вызовы виртуальных методов класса можно производить по их именам, а остальных методов – через их указатели, полученные ранее; - создание объекта класса должно выполняться явно, для чего вначале потребуется выделить память под объект (статически или динамически), а затем явно вызвать конструктор класса через его указатель; - уничтожение объекта класса должно выполняться также явно, для чего необходимо явно вызвать деструктор класса через указатель, передав ему адрес объекта, а затем освободить ранее выделенную память. Рассмотрим реализацию указанных выше действий на следующем примере. Пример. В предыдущей лекции (Создание DLL) приведено описание заголовочного файла и исходного кода библиотеки динамической компоновки MyDLL.dll, содержащей класс MyDLLClass, в котором имеются: конструктор MyDLLClass(), деструктор ~MyDLLClass(), не виртуальная функция ClMyFunc() и виртуальная функция ClVirtFunc(). Необходимо создать приложение MyDLLApp1.exe, которое явно загрузит указанную DLL, создаст объект класса MyDLLClass и вызовет названные выше методы класса (кроме виртуальных) через их порядковые номера. С помощью утилиты DUMPBIN.EXE (с ключом /EXPORTS) можно получить содержимое секции экспорта в библиотеке MyDLL.dll, чтобы определить порядковые номера функций класса MyDLLClass. Для этого необходимо записать в командной строке для текущего каталога следующее: DUMPBIN.EXE /EXPORTS MyDLL.dll /OUT:"ExportSection.txt" В результате выполнения этой команды в текстовом файле ExportSection.txt будет записано содержимое секции экспорта библиотеки MyDLL.dll, которое в сокращенном виде выглядит следующим образом: Dump of file MyDLL.dll File Type: DLL Section contains the following exports for MyDLL.dll … ordinal hint RVA name
1 0 00001023??0MyDLLClass@@QAE@ABV0@@Z 2 1 00001014??0MyDLLClass@@QAE@XZ 3 2 00001028??1MyDLLClass@@QAE@XZ 4 3 00001005??4MyDLLClass@@QAEAAV0@ABV0@@Z 5 4 0002901C??_7MyDLLClass@@6B@ 6 5 0000101E?ClMyFunc@MyDLLClass@@QAEHXZ 7 6 0000100F?ClVirtFunc@MyDLLClass@@UAEHXZ 8 7 0000100A MyDLLFunction 9 8 0002E3F0 nMyDLLVar … Из этого файла можно определить порядковые номера (ordinal) требуемых методов класса: - конструктор MyDLLClass() – 2; - деструктор ~MyDLLClass() – 3; - не виртуальная функция ClMyFunc() – 6; - виртуальная функция ClVirtFunc() – 7, но этот номер не потребуется. В файле MyDLLApp1.cpp с исходным кодом программы MyDLLApp1.exe, которая явно загружает библиотеку MyDLL.dll необходимо записать следующее: Файл MyDLLApp1.cpp #include "stdafx.h" #include "MyDLL.h" …// Явная загрузка библиотеки MyDLL.dllHMODULE hMyDll = LoadLibrary("MyDLL.dll"); …// Объявление указателя на конструктор класса и получение его адреса void (MyDLLClass:: *pConstructor)(); (FARPROC &) pConstructor = GetProcAddress(hMyDll, MAKEINTRESOURCE(2));// Выделение памяти в куче для объекта класса MyDLLClassMyDLLClass *pObj = (MyDLLClass *) new char[sizeof(MyDLLClass)];// Вызов конструктора через указатель и создание объектаpObj->pConstructor(); … // Объявление указателя на метод ClMyFunc() и получение его адреса int (MyDLLClass:: *pClMyFunc)();(FARPROC &) pClMyFunc = GetProcAddress(hMyDll, MAKEINTRESOURCE(6));// Вызов метода ClMyFunc() через указатель на негоint iRez1 = pObj->pClMyFunc();// Вызов виртуальной функции ClVirtFunc() производится напрямую – // по имени, через таблицу адресов виртуальных функций vtable int iRez2 = pObj->ClVirtFunc(); … // Объявление указателя на деструктор класса и получение его адреса void (MyDLLClass:: *pDestructor)(); (FARPROC &) pDestructor = GetProcAddress(hMyDll, MAKEINTRESOURCE(3));// Вызов деструктора через указатель и уничтожение объектаpObj->pDestructor();// Освобождение памяти в кучеdelete [ ] pObj; … // Выгрузка библиотеки MyDLL.dll FreeLibrary(hMyDll);
Дата добавления: 2014-01-14; Просмотров: 888; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |