При разработке dll библиотеки необходимо понимать, что она вполне может быть использована в проекте, который написан на совершенно другом языке программирования. Поэтому, если библиотека предполагает использование в других проектах и, тем более, распространение имеет смысл позаботиться об обеспечении совместимости.
Так как Delphi и C++ Builder входят в один пакет RAD Studio решения, разработанные в них, часто интегрируются между собой. Но, сделать это не всегда просто.
Как известно, Delphi и C++ по по-разному обрабатывают стек. Поэтому использование библиотек написанных на C++ в проектах на Delphi часто порождает серьёзные трудности вплоть до невозможности работы с библиотекой.
Чтобы этого избежать, необходимо задать стандарт вызова stdcall, который нивелирует эти различия.
Также в dll, которая будет использоваться в проекте на Delphi ,необходимо задать внешнюю компоновку (что это такое можно узнать здесь на примере Microsoft Visual C++) каждой экспортируемой функции с помощью ключевого слова extern. Иначе Delphi просто не «увидит» экспортируемую функцию.
Ниже приведён пример простейшей dll библиотеки написанной на C++ Builder, которая полностью корректно работает с Delphi. Библиотека содержит одну единственную функцию, которая возвращает число, переданное ей в качестве аргумента.
Файл исходного кода (cpp) выглядит следующим образом:
1 2 3 4 5 6 7 8 9 10 11 |
#include #include #pragma hdrstop #pragma argsused int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved) { return 1; } extern "C" int __stdcall __declspec(dllexport) dllFunc(int a) { return a; } |
Экспортируемую функцию dllFunc указываем в файле заголовка. Объявления экспортируемых функций в файлах исходного кода и заголовка должны быть абсолютно идентичными.
1 2 3 |
#include #include extern "C" int __stdcall __declspec(dllexport) dllFunc(int a); |
На стороне Delphi работа с такой библиотекой ничем не отличается от работы с обычными библиотеками, написанными на Delphi.
1 2 3 4 5 |
function dllFunc(a:integer):integer; stdcall; external 'test.dll'; procedure TMainForm.TestBtnClick(Sender: TObject); begin OutputNumber.Caption:=IntToStr(dllFunc(StrToInt(InputNumber.Text))); end; |
Результат выполнения данной программы на Delphi показан на скриншоте.
Огромное спасибо!!! Эту информацию искал пол дня! Все стандартные примеры, которые находятся по запросам типа «написание dll C++ Builder», выдают вполне рабочие примеры, но из за особенностей компилятора к экспортируемому имени функции добавляется символ «_». В итоге, в собственном коде я делаю функцию Name(), а в dll она входит как _Name. Из за этого, стороннее приложение (написанное не мной), которое пытается вызвать из DLL функцию Name, не может ее получить. Еще раз огромное спасибо!