Форум: "Прочее";
Текущий архив: 2009.10.11;
Скачать: [xml.tar.bz2];
Внизdelphi и dll - проблема, рекомендуйте плиз о чём почитать... Найти похожие ветки
← →
yantux © (2009-08-07 12:13) [0]Если вызываю функцию dll из главного блока программы begin end; то всё ок, если вызываю функцию dll из процедуры или функции, то программа падает, пишет, что попытка записать по адресу 0х0
dll сделана с помощью компилятора gcc 3.4.2 среда разработки dev-cpp
почему из функции или процедуры нельзя вызвать dll? как с этим бороться?
Вообще по ходу Delphi не умеет нормально работать с dll. А именно, сделал dll в Borland C++ Builder, функция вызывается (из процедуры и функции) корректно, если фугкция внутри dll не содержит аргументов.
АПочему так? На какую тему надо проработать документацию, чтобы решить эту проблему?
← →
DVM © (2009-08-07 12:34) [1]
> Вообще по ходу Delphi не умеет нормально работать с dll.
Походу с DLL не умеешь работать ты.
> Если вызываю функцию dll из главного блока программы begin
> end; то всё ок, если вызываю функцию dll из процедуры или
> функции, то программа падает, пишет, что попытка записать
> по адресу 0х0
Переменные какие передаются в функции DLL ? Может они глобальными должны быть а не локальными?
← →
Владислав © (2009-08-07 12:38) [2]Почитать на тему соглашения о вызовах.
← →
yantux © (2009-08-07 12:52) [3]переменные объявлены в главном блоке var, откуда их видят все процедуры
выяснилось, что Delphi нормально кушает, только dll своей сборки, а dll сборки gcc, Borland c++ builder не ест, т.е. не ест именно те фукции, у которых есть аргументы и не ест именно в том, случае, если вызываются они не в главном блоке программы, а из процедуры или функции.
← →
yantux © (2009-08-07 12:56) [4]не ест- это значит вылетает с исключением, что происходит доступ к памяти 0х0
>Почитать на тему соглашения о вызовах.
что оно может дать? и как локализовать проблему? всё делаю по документации
Мне кажется, тут есть какаято особенность именно Delphi, потому что с другими яыками вроде такого ен наблюдалось, проверю.
← →
Сергей М. © (2009-08-07 12:58) [5]
> всё делаю по документации
В приличной док-ции должно быть оговорено соглашение о вызове
← →
Юрий Зотов © (2009-08-07 13:07) [6]> yantux © (07.08.09 12:52) [3]
> выяснилось, что Delphi нормально кушает, только dll своей сборки
Вы не поверите - Delphi нормально кушает ЛЮБЫЕ DLL. Если конечно, сами эти DLL тоже нормальные.
Например, практически любая Delphi-программа грузит кучу системных библиотек, которые вообще на C писаны. И никаких "по адресу 0х0", все в прорядке.
Вывод напрашивается, не так ли?
← →
Юрий Зотов © (2009-08-07 13:10) [7]> На какую тему надо проработать документацию
1. Соглашения о вызове (см. в справке тему Calling conventions).
2. Не использовать в качестве параметров и результатов функций специфические Дельфишные типы (строки, динамические массивы и т.п.).
← →
yantux © (2009-08-07 13:24) [8]Есть результаты.
Соглашения о вызовах почитал для dll и gcc. там было сказано о stdcall и cdecl. Я по образованию не программер, поэтому не очень понимаю. Насколько я понял, компилер както по другому делает вызов функции на уровне машинного кода.
В общем, если функции продеклалированы с stdcall, то нормально вызываются dll собранные в Delphi, а если cdecl, то нормально вызываются dll собранные в gcc 3.4.2, среда dev-cpp
Буду тестить с Борланлоим бюлдером с++ , ожидаю результат, как и с gcc.
← →
DVM © (2009-08-07 13:27) [9]
> yantux © (07.08.09 13:24) [8]
> В общем, если функции продеклалированы с stdcall, то нормально
> вызываются dll собранные в Delphi, а если cdecl, то нормально
> вызываются dll собранные в gcc 3.4.2, среда dev-cpp
Может ты dll неправильно оформляешь?
← →
Inovet © (2009-08-07 13:33) [10]> [8] yantux © (07.08.09 13:24)
> Есть результаты.
>
> Соглашения о вызовах почитал для dll и gcc. там было сказано
> о stdcall и cdecl. Я по образованию не программер, поэтому
> не очень понимаю. Насколько я понял, компилер както по другому
> делает вызов функции на уровне машинного кода.
Передача параметров может быть даже очень сильно по разному.
> В общем, если функции продеклалированы с stdcall, то нормально
> вызываются dll собранные в Delphi, а если cdecl, то нормально
> вызываются dll собранные в gcc 3.4.2, среда dev-cpp
Одинаковые должны быть как в DLL так и в Delphi.
← →
Юрий Зотов © (2009-08-07 13:33) [11]> yantux © (07.08.09 13:24) [8]
Чтобы Delphi-программа могла вызвать функцию DLL, в ней должен быть объявлен прототип этой функции (см., например, Windows.pas). Так вот - этот прототип должен быть объявлен с тем же соглашением о вызове, что был использован компилятором DLL. Только и всего.
← →
yantux © (2009-08-07 14:13) [12]На этапе разработки dll, в исходных текстах я не определяю stdcall и cdecl для gcc и билдера. Возможно в опциях компиляции она задаются по умолчанию, при чём разные для Delphi и borlad C++ Builder.
Но если в прогремме, вызывающей dll установить cdecl для dll разработанные в gcc, Borland Builder C++ вызовется коректно, а dll разработанная в Delphi корректно вызовется с stdcall.
Странно, что об этой проблеме совместимости не сказано в книжках(про 16 и 32 разрадяные сказано, а про stdcall и cdecl нет), в документации по разработке dll ни в gcc, ни в Borlad Builder C++, ни в Delphi.
В общем, проблема решена, всем спасибо. Думаю можно добавить в faq Delphi, Lazarus, gcc, Borland Builder C++.
← →
@!!ex © (2009-08-07 14:20) [13]> [12] yantux © (07.08.09 14:13)
Пишут об этом в книжках.
Для винды стандартом являеться stdcall, что явно и нужно указывать.
← →
Inovet © (2009-08-07 14:49) [14]> [12] yantux © (07.08.09 14:13)
> Но если в прогремме, вызывающей dll установить cdecl для
> dll разработанные в gcc, Borland Builder C++ вызовется коректно,
> а dll разработанная в Delphi корректно вызовется с stdcall.
В Си++ и Делфи по умолчанию разный механизм передачи параметров и освобождения стека. Подумай как на Паскале написасть printf(), в которой количество и тип параметров известны вызывающей стороне.
И см.
> [13] @!!ex © (07.08.09 14:20)
← →
DVM © (2009-08-07 14:53) [15]
> Подумай как на Паскале написасть printf(), в которой количество
> и тип параметров известны вызывающей стороне
Количество и тип параметров в printf не имеют отношения к соглашениям вызова.
Printf определяет количество и тип параметров разбирая строку форматирования.
← →
Inovet © (2009-08-07 14:59) [16]> [15] DVM © (07.08.09 14:53)
> Количество и тип параметров в printf не имеют отношения
> к соглашениям вызова.
> Printf определяет количество и тип параметров разбирая строку
> форматирования.
Ну дык сначала их нужно передать, потом освободить стек.
← →
Холивар (2009-08-07 20:04) [17]
> yantux © (07.08.09 12:52) [3]
>
> переменные объявлены в главном блоке var, откуда их видят
> все процедуры
>
> выяснилось, что Delphi нормально кушает, только dll своей
> сборки, а dll сборки gcc, Borland c++ builder не ест, т.
> е. не ест именно те фукции
cdecl;?
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2009.10.11;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.005 c