Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.10.11;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.01 c
1-1219162412
yaric
2008-08-19 20:13
2009.10.11
Отрисовка TRichEdit


2-1249632868
_Андрей
2009-08-07 12:14
2009.10.11
TList & records


2-1249977509
Foster14
2009-08-11 11:58
2009.10.11
Работа с БД IB


15-1249710891
Alexey
2009-08-08 09:54
2009.10.11
Delphi 7 и Windows 7


10-1159967954
Godness
2006-10-04 17:19
2009.10.11
Как вызвать OleContainer из потока?