Читать реферат по информатике, вычислительной технике, телекоммуникациям: "Создание в среде Borland C++ Builder dll, совместимой с Visual C++" Страница 3

назад (Назад)скачать (Cкачать работу)

Функция "чтения" служит для ознакомления с работой. Разметка, таблицы и картинки документа могут отображаться неверно или не в полном объёме!

базового порядкового номера экспорта функций для данного PE-файла, вычисляется индекс, по которому из массива адресов извлекается искомый RVA функции. Помимо экспорта по имени возможен экспорт функций по их порядковым номерам (ordinal). В этом случае последовательность действий для получения индекса элемента из массива относительных виртуальных адресов сводится только к преобразованию порядкового номера функции. Для экспорта функций по номеру используется .def-файл с секцией EXPORTS, где за каждой функцией будет закреплен порядковый номер. При этом в тексте самой dll функции как экспортируемые не помечаются. Подробнее о таблице экспорта можно прочитать в статье по адресу http://www.rsdn.ru/article/baseserv/pe_coff.xml.

ExplicitDll.cpp

#include #include #include "ExplicitDll.h"int __cdecl SumFunc(int a, int b){ return a + b;}HWND __stdcall ViewStringGridWnd(int Count, double* Values){ try { // создаем VCL-форму, на которой будет отображен StringGrid, // и задаем ее основные параметрыTForm* GridForm = new TForm((TComponent *)NULL);GridForm->Caption = "Grid Form"; GridForm->Width = 300; GridForm->Height = 300; // создаем компонент StringGrid и устанавливаем его размеры TStringGrid *Grid = new TStringGrid(GridForm); Grid->ColCount = Count + 1; Grid->RowCount = Count + 1; // заполняем StringGrid значениями if (Values != NULL) for (int i = 0; i < count; i++) grid->Cells[i + 1][i + 1] = Values[i]; // задаем параметры отображения StringGrid в родительском окне Grid->Parent = GridForm; Grid->Align = alClient; // показываем VCL-форму GridForm->Show(); // возвращаем хэндл VCL-окна клиентскому приложению,// дабы оно могло это окно при необходимости закрыть return GridForm->Handle; } catch(...) { return NULL; }}#pragma argsusedint WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved){ return 1;}

Проанализируем сформированные компилятором наименования экспортируемых функций. Воспользовавшись утилитой impdef.exe, поставляемой совместно с C++Builder (находится в каталоге $(BCB)\Bin, синтаксис командной строки – impdef.exe ExplicitDll.def ExplicitDll.dll), получим следующий .def-файл

ExplicitDll.def

LIBRARY EXPLICITDLL.DLLEXPORTS ViewStringGridWnd @1 ; ViewStringGridWnd _SumFunc @2 ; _SumFunc ___CPPdebugHook @3 ; ___CPPdebugHook

Поскольку в данном примере экспортируемая функция ViewStringGridWnd использует соглашение __stdcall, ее имя осталось неизменным (см. таблицу 1), следовательно, для вызова этой функции VC-приложение воспользуется именем ViewStringGridWnd (например, при вызове GetProcAddress), а вот для вызова функции SumFunc использовать придется имя _SumFunc. Очевидно, что осуществлять вызов функции, пользуясь ее измененным именем, неудобно само по себе, а тем более, если dll пишет один программист, а работает с ней другой. Для того чтобы при использовании __cdecl-соглашения экспортируемые функции можно было использовать с их истинными именами (без символов подчеркивания), необходимо об этом позаботиться заранее, то есть на этапе создания самой dll. Для этого создается .def-файл (это можно сделать в любом текстовом редакторе), в котором определяется секция EXPORTS, содержащая псевдоним (alias) для каждой экспортируемой __cdecl-функции. В нашем случае он будет выглядеть следующим образом

ExplicitDllAlias.def

EXPORTS ; VC funcname = BCB funcname SumFunc = _SumFunc

То есть, у функции, экспортируемой как _SumFunc, будет псевдоним SumFunc, который мы исключительно для удобства делаем идентичным оригинальному имени этой функции в коде (хотя псевдоним может быть каким угодно).

Созданный .def-файл добавляется (Project -> Add to Project) к проекту dll. После компиляции, проанализировав dll c помощью impdef.exe, получим следующее

ExplicitDll.def

libRARY EXPLICITDLL.DLLEXPORTS SumFunc @4 ; SumFunc ViewStringGridWnd @2 ;


Интересная статья: Основы написания курсовой работы