Главная » C++, C++ Builder » Создание DLL в CBuilder

0

Для того чтобы использовать код в DLL, нам сначала нужно  создать  DLL,  содержащую  код, верно? Верно. Давайте создадим такого зверя в CBuilder. Далее мы исследуем использование DLL, созданной в CBuilder, в другой системе, однако сейчас мы собираемся загружать эту DLL в CBuilder.

Одно небольшое замечание. На самом деле есть два разных способа использовать функции в DLL, созданной в CBuilder. Первый — это создание библиотеки импорта утилитой implib, которая поставляется вместе с CBuilder. Затем библиотека импорта может быть напрямую встроена в приложение, и Windows автоматически загрузит вашу DLL во время выполнения. Запомните, что вам нужно использовать программу implib, поставляемую с CBuilder, а не более древнюю версию из другой системы, так как библиотеки CBuilder имеют  другой  формат,  нежели  старые библиотеки, и поэтому нужны свежие программы для генерации этих библиотек из DLL. Когда у вас есть библиотека импорта для  вашей DLL, вы можете просто описать прототипы функций, которые вам нужны, и использовать их напрямую, как будто они были описаны в вашем приложении. В нашем примере мы более заинтересованы в механизме динамической загрузки, так что мы все сделаем сами.

В этом примере мы создадим DLL в другой среде разработки, в данном случае — в Visual C++. Я выбрал эту среду отчасти оттого, что я хорошо знаю Visual C++, но в основном потому, что вы скорее будете использовать DLL из других  источников  (так  называемые  third-party),  чем созданные в CBuilder. В любом случае нам нужно делать одно и то же, так почему бы не показать вам еще кое-что?

В отличие от CBuilder среда Visual C++ (VC) не хочет сама создавать для вас DLL. Вместо этого она создаст файл сборки (makefile) и оставит его пустым, без исходных файлов. Как мне кажется, это еще одна веская причина для перехода на CBuilder. В любом случае создайте в Visual C++ новый файл и добавьте в него следующий код. Если у вас нет Visual C++ или вам лень загружать эту среду разработки и набирать весь этот код, вы можете найти данную DLL вместе с кодом примера на сопроводительном компакт-диске.

#include <windows.h>

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

BOOL WINAPI DllEntryPoint (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {

BOOL fSuccess = TRUE; switch (fdwReason) {

case  DLL_PROCESS_ATTACH: case  DLL_THREAD_ATTACH:

break;

case  DLL_PROCESS_DETACH: case  DLL_THREAD_DETACH:

break;

}

return (fSuccess);

}

extern "C"

{

__declspec( dllexport ) int CalFunction1( void )

{

MessageBox(NULL, "You called function 1", "Info", MB_OK); return 0;

}

__declspec( dllexport ) int CallFunction2( const char *str )

{

MessageBox(NULL, "You called function 2", str, MB_OK); return 0;

}

__declspec( dllexport ) void CallFunction3( int nValue )

{

char szBuffer[20]; sprintf(szBuffer, "%d", nValue);

MessageBox(NULL, szBuffer, "Value", MB_OK);

}

}

Важным в этом коде являются три функции. Пока что вы можете игнорировать смешно выглядящие модификаторы declspec (dllexport). Это просто способ объяснить VC, что эти функции должны быть экспортируемыми в DLL, чтобы другие программы могли их использовать. Может быть, вы думали, что функции экспортируются по умолчанию; в таком случае многое в мире программирования под Windows является не таким, каким оно вам казалось.

В DLL определены три функции: CallFunction1, CallFunction2 и CallFunction3. Они отличаются типом возврата, а также количеством и типами аргументов. Мы будем использовать все три функции в нашем примере.

ЗАМЕЧАНИЕ

Как вы заметили, функции объявлены с модификатором extern «C» в предыдущем листинге. Visual C++ и CBuilder используют разные схемы изменения имени (mangling) при генерации имен для функций. Чтобы не смотреть в листинг экспорта и запоминать полученные имена функций в переделанном виде, мы разрешаем компилятору использовать соглашение о  вызовах,  а  также схему внешних имен, принятые в C. Это означает, что в результате имена функций в экспортном виде будут просто CallFunction1 и т. д.

Когда мы определили DLL, следующим шагом является создание проекта в CBuilder, использующего функции, которые мы написали и экспортировали из DLL. Вы должны знать, что только экспортированные функции могут быть динамически загружены из DLL  во  время выполнения или встроены  в ваше приложение через  библиотеку импорта. Неэкспортированные функции невидимы для окружающего мира и могут быть  использованы  только  другими функциями в этой DLL. Мы используем эту возможность ниже в книге,  когда  будем рассматривать другую часть уравнения: использование DLL, созданных в CBuilder,  в  системе Visual C++.

Источник: Теллес М. – Borland C++ Builder. Библиотека программиста – 1998

По теме:

  • Комментарии