Правильная компиляция DLL в VC для использования в Delphi

Модераторы: Duncon, Naeel Maqsudov, Игорь Акопян, Хыиуду

Ответить
WerewolfGSM
Сообщения: 1
Зарегистрирован: 08 ноя 2006, 10:18

Есть такая проблема.
Есть необходимость в использовании mySQL embedded server версии 4.1 или 5.0 в Delphi приложении (используются компоненты myComponents от SciBit).
Библиотека отвечающая за embedded server (libmysqlD.dll) должна быть компилировна в VC 2003. После компиляции при использовании библиотеки возникает ошибка .... Access Violation in ntdll.dll..... Read of adress ABABABB3....
Причем если компилирую как release одни ошибки, если как classic другие, а если debug - ругается регулярно и много...
На форуме SciBit ответили что надо компилировать с учетом настроек необходимых для DLL предназначеных для Delphi. Так вот вопрос, какие это настройки и установки. Как надо компилировать эту библиотеку, чтобы ее можно было использовать в Delphi.
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Как надо компилировать эту библиотеку, чтобы ее можно было использовать в Delphi
Может, просто в Delphi надо вызывать ее методы с соглашением о вызове, принятым в C/C++ - параметры кладутся в стек в обратном порядке, чистит стек вызывающий. В VC++ такой формат вызова называется __cdecl, как он называется в Delphi смотри документацию. Если никак, то надо в настройках проекта VC++ установить дефолтовый формат вызова __stdcall, но это будет работать только в том случае если библиотека не использует методы с переменным числом параметров - для переменного числа параметров работает только __cdecl.
2B OR NOT(2B) = FF
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Про VC 2003. Вот DLL, скомпилированную под VC60 в Delphi подцеплять приходилось. Надеюсь, принцип тот же.

Собственно, я так понимаю, что "решение всех бед" - использовать аналогичные соглашения передачи параметров при вызове функций.

1. Часть первая.
При описании экспортируемой Си-шной функции (Пусть наша DLL называется MyCPP.DLL) используем модификатор WINAPI (набор параметров, ясное дело, может быть произвольным):

Код: Выделить всё

extern "C" long WINAPI __declspec(dllexport)
     FuncForExport (void*  pParam1,
                            ULONG   uiParam2);
__declspec(dllexport) здесь можно не писать, если использовать....:

2. Шаг два
... экспорт-файл. Где, помимо того, что указывается, что функция экспортируется DLL-ю, можно еще указать "более человеческое" имя функции, которое будет использоваться при экспорте. Так как, несмотря на использование в п.1 extern "C", Microsoft C все равно в хвост функции приписывает число - что-то вроде количества байт, которые кладутся в стек при передаче параметров, а спереди приделывает символ подчеркивания.

Export-файл (который затем нужно подключить в проект) для примера выше будет выглядеть так:

Код: Выделить всё

EXPORTS
   FuncForExport  = _FuncForExport@8
3. Шаг три.
В Delphi создается unit-"посредник". Для нашего примера он будет иметь такой вид:

Код: Выделить всё

unit Ext_DLL;

interface

function FuncForExport (
                  pParam1 : pointer;
                  uiParam2 : Longword) : longint; stdcall;

implementation

function FuncForExport (
                  pParam1 : pointer;
                  uiParam2 : Longword) : longint; stdcall;
           external 'MyCPP.DLL' name 'FuncForExport';

end.
Вот, собственно, в общих чертах, и все.
В Дельфийном проекте делаем Uses Ext_DLL и вызываем FuncForExport

Ну и еще, конечно, надо следить за совместимостью типов параметров экспортируемых процедур в текстах C и Delphi. То есть, представлять, какой тип данных в одном языке соответствует какому типу данных в другом.
Ответить