Реферат: Создание в среде Borland C++ Builder dll, совместимой с Visual C++
ExplicitDll.def
libRARY EXPLICITDLL.DLL EXPORTS SumFunc @4 ; SumFunc ViewStringGridWnd @2 ; ViewStringGridWnd _SumFunc @1 ; _SumFunc ___CPPdebugHook @3 ; ___CPPdebugHook |
Имеем на одну экспортируемую функцию больше, но при этом реальное количество функций в dll осталось неизменным, а функция с именем SumFunc (функция-псевдоним) является ссылкой на свой оригинал, то есть на функцию, экспортируемую под именем _SumFunc.
ПРИМЕЧАНИЕ Более правильным будет сказать, что функция-псевдоним попросту добавляется в таблицу экспорта dll: ее имя SumFunc добавляется в массив имен функций, а в массив порядковых номеров добавляется присвоенный ей порядковый номер. Однако соответствующий функции-псевдониму RVA в массиве относительных виртуальных адресов будет равен RVA функции с именем _SumFunc. Убедиться в этом можно последовательно вызывая GetProcAddress для имен функций SumFunc и _SumFunc и анализируя возвращаемый адрес (можно, разумеется, воспользоваться различными программами, позволяющими просмотреть содержимое исполняемого файла). В обоих случаях адрес функции будет одинаков. |
Таким образом, с помощью .def-файла псевдонимов при экспорте функций, определенных как __cdecl, мы избавляем пользователей от необходимости вызова функций по их измененным именам, хотя и такая возможность остается.
ПРЕДУПРЕЖДЕНИЕ Поскольку __stdcall- и __cdecl-функции по-разному работают со стеком, не пытайтесь из клиентского приложения вызывать __stdcall-функции как __cdecl, и наоборот, иначе стек будет поврежден, и дальнейшее выполнение приложения будет невозможно. |
В результате изложенного выше мы получили dll, экспортирующую функции с именами SumFunc и ViewStringGridWnd. При этом их названия не зависят от того, какое соглашение о вызове использовалось при объявлении этих функций. Теперь рассмотрим пример использования нашей dll в приложении VC. Создадим в среде Visual C++ 6.0 (или Visual C++ 7.0) простое MFC-приложение, которое будет представлять собой обычное диалоговое окно (File -> New -> MFC AppWizard(exe) -> Dialog based -> Finish). Добавим к исходному диалогу две кнопки: кнопку “SumFunc” и кнопку “ViewStringGridWnd”. Затем для каждой кнопки создадим обработчик события BN_CLICKED: OnSumFunc() и OnViewStringGridWnd() соответственно. Нам также понадобятся обработчики сообщений для событий формы WM_CREATE и WM_DESTROY. Полный рабочий код этого приложения находится в примерах к статье, здесь же будет приведена только часть, демонстрирующая работу с нашей dll, поскольку оставшаяся часть кода генерируется средой разработки.
Листинг 2 - Компилятор Visual C++ 6.0
UsingExplicitDLLDlg.cpp
// код, генерируемый средой разработки … // хэндл тестируемой DLL HINSTANCE hDll = NULL; // тип указателя на функцию ViewStringGridWnd typedef HWND (__stdcall *ViewStringGridWndProcAddr) (int Count, double* Values); // хэндлокнас VCL-компонентом StringGrid HWND hGrid = NULL; // тип указателя на функцию SumFunc typedef int (__cdecl *SumFuncProcAddr) (int a, int b); // код, генерируемый средой разработки … // обработчик нажатия кнопки SumFunc К-во Просмотров: 494
Бесплатно скачать Реферат: Создание в среде Borland C++ Builder dll, совместимой с Visual C++
|