Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];

Вниз

Сишные Указатели на функции и их интерпретация в Дельфи   Найти похожие ветки 

 
афвуд   (2004-01-14 15:50) [0]

В DLL(дельфийскую) передаётся в качестве параметра указатель на функцию из программы сишной. Получаю его так:

Type TGetVarFunction = function (ptr:Pointer;VarName:PChar):Variant;stdcall;
.................
procedure Exec(P:Pointer);stdcall;
var GetVar:TGetVarFunction;
..................
GetVar:=TGetVarFunction(p);


При вызове GetVar ошибка "External Exception". Никто не встречался?


 
Тимохов   (2004-01-14 16:03) [1]

может cdecl?


 
афвуд   (2004-01-14 16:05) [2]

>cdecl
А что это такое?


 
Тимохов   (2004-01-14 16:06) [3]

Ну ты пишешь же stdcall.
Почему именно stdcall?


 
афвуд   (2004-01-14 16:12) [4]

А у нас договоренность с тем кто пишет прогу(я DLL-ку пишу) ВСЕ функции адреса которых могут быть переданы в DLL будут stdcall - причём если я DLL пишу в С++ Билдере то всё путём.


 
Digitman   (2004-01-14 16:33) [5]

сдается мне, что С++ не знает никаких дельфийских "variant"


 
афвуд   (2004-01-14 16:34) [6]

Это С++ BUILDER. Он знает VCL.


 
афвуд   (2004-01-14 16:35) [7]

И Variant тоже. Мы его юзаем везде. И везде работает.


 
Skier   (2004-01-14 16:35) [8]

>афвуд © (14.01.04 16:34) [6]
А покажи-ка код полностью.


 
афвуд   (2004-01-14 16:43) [9]

А я почти всё показал.

Type TGetVarFunction = function (ptr:Pointer;VarName:PChar):Variant;stdcall;
.................
procedure Exec(P:Pointer);stdcall;
var GetVar:TGetVarFunction;
begin
..................
GetVar:=TGetVarFunction(p);
ShowMessage(GetVar(p,PChar("par")));//именно вот здесь ошибка,
{а если смотреть через CPU Window, то просто адрес по которому зовётся(call) функция, ведёт не туда куда надо.}
.....
end;


 
Тимохов   (2004-01-14 16:46) [10]

Интересно, а зачем адрес фукнции передавать как ее же параметр?
А вы уверены, что эта самая getvar не меняет VarName?


 
афвуд   (2004-01-14 16:50) [11]

>Интересно, а зачем адрес фукнции передавать как ее же параметр?
>А вы уверены, что эта самая getvar не меняет VarName?
Хм... даже не понимаю.. видать немного невнимательно смотрели код. Никакой передачи функцие указатель на саму себя нет.

Хорошо могу вместо последнего ShowMessage написать

GetVar(<Здесь ЛЮБОЙ ПОИНТЕР всё падает при ВЫЗОВЕ>,PChar("par"));

Всё равно ошибка.


 
icWasya   (2004-01-14 16:50) [12]

и немножко кода на Си


 
Тимохов   (2004-01-14 16:52) [13]


> Хм... даже не понимаю.. видать немного невнимательно смотрели
> код. Никакой передачи функцие указатель на саму себя нет.


GetVar:=TGetVarFunction(p);
ShowMessage(GetVar( p,PChar("par")));
Жирненьким это что?

Повторюсь: "А вы уверены, что эта самая getvar не меняет VarName?"


 
афвуд   (2004-01-14 16:52) [14]

typedef void (*Pointer);
Pointer a;
a=GetVar;
void (__stdcall *Exec)(void (*ptr));
Exec = (void(__stdcall *) (void (*ptr)))GetProcAddress(dllp, "_Exec");
if(Exec) Exec(a);


Примерно так..


 
афвуд   (2004-01-14 16:53) [15]

>GetVar:=TGetVarFunction(p);
>ShowMessage(GetVar(p,PChar("par")));
>Жирненьким это что?

Я просто написал p вместо того что я там передаю что сократило код :)


 
Тимохов   (2004-01-14 16:55) [16]

А саму GetVar?


 
Verg   (2004-01-14 16:57) [17]


> {а если смотреть через CPU Window, то просто адрес по которому
> зовётся(call) функция, ведёт не туда куда надо.}


Значит в Exec передается указатель не туда.


 
Digitman   (2004-01-14 17:08) [18]

а где SрareMem ?


 
Sli   (2004-01-14 17:08) [19]

Variant __stdcall GetVar(void * ptr, char * str)
{
.......
}

PS: я это тот кто пишет прогу которая вызывает Dll.


 
Тимохов   (2004-01-14 17:10) [20]

Повторюсь: "А вы уверены, что эта самая getvar не меняет второй параметр?"


 
афвуд   (2004-01-14 17:15) [21]

>Повторюсь: "А вы уверены, что эта самая getvar не меняет второй параметр?"

Я же говорю, что ошибка при ВЫЗОВЕ функции GetVar(она не успевает вообще ничего сделать)и ещё: реально я ей передаю совершенно другой укзатель, а p написал здесь для краткости.


 
AKul   (2004-01-14 17:26) [22]


> афвуд © (14.01.04 17:15) [21]


снасала ты писал:
> {а если смотреть через CPU Window, то просто адрес по которому
> зовётся(call) функция, ведёт не туда куда надо.}


Потом написал:

> Я же говорю, что ошибка при ВЫЗОВЕ функции GetVar( она не успевает вообще ничего сделать)



Так как это понимать? Уточни пожайлуста вызывается она или нет.
Если call ведет не туда куда надо, то проверь передаваемый указатель...


 
Тимохов   (2004-01-14 17:28) [23]

AKul © (14.01.04 17:26) [22]
Вот-вот, пусть ответит. Не один я непонимающий :)))

Мой диагноз, что вызов происходит, и в С просто меняется второй параметр.


 
Sli   (2004-01-14 17:37) [24]

все падает при попытке вызова функции по указателю.... выполнение уходит в непонятную область где кода вообще нет, там просто данные.
Самое интересное что адрес действительно левый ( дебагером смотрел), но в dll на входе он как раз тот что нужен и когда он слетает непонятно


 
AKul   (2004-01-14 17:40) [25]


> Sli (14.01.04 17:37) [24]



> Самое интересное что адрес действительно левый ( дебагером
> смотрел), но в dll на входе он как раз тот что нужен и когда
> он слетает непонятно


Выполни пошаговую отладку и найдешь в каком месте он портится.


 
Sli   (2004-01-14 17:49) [26]

> Выполни пошаговую отладку и найдешь в каком месте он портится.

В том то и дело отладчик борланда показывает что все хорошо указатель туда куда нужно, а прсмотр кода ( cpu view ) показывает что он прыгает не туда (не по тому адресу что в переменной)


 
Digitman   (2004-01-14 17:52) [27]


> он прыгает не туда


не городи ерунду
чудес не бывает


 
Тимохов   (2004-01-14 17:54) [28]

Думаю, что это типичная 17ая строка... :((
Вряд ли так можно помочь...


 
Sli   (2004-01-14 18:02) [29]

> не городи ерунду
> чудес не бывает

я тоже так думал :-) но как выясняется что так, может компилер что то не так понимает....

> Думаю, что это типичная 17ая строка...

что имеется ввиду ???


 
AKul   (2004-01-14 18:02) [30]

Постоянно следи за указателем (cpu view).

Посмотри на входе процедуры, после инициализации фрейма стека ([ebp+8] кажется)

Посмотри при вызове
будет что-то типа: (зависит от оптимизации и версии компилятора)
mov eax,[ebp+8]
...
push....
push...
call eax ;или call [ebp+8]

внимательнее смотри!


 
alex_***   (2004-01-14 18:03) [31]

В том то и дело отладчик борланда показывает что все хорошо указатель туда куда нужно, а прсмотр кода ( cpu view ) показывает что он прыгает не туда (не по тому адресу что в переменной)


Ну и отлаживайтесь принтами типа ShowMessage();


 
Семен Сорокин   (2004-01-14 18:06) [32]

<offtop>странно начинал афвуд, продолжает Sli.
передача эстафеты :)</offtop>


 
афвуд   (2004-01-14 18:19) [33]

Я не выключился просто молчу.

>Ну и отлаживайтесь принтами типа ShowMessage();

C этого я и начинал. НО всё гораждо глубже...


 
Sandman25   (2004-01-14 18:41) [34]

Наверное, я задам тупой вопрос, но все-таки. Разве не нужно как-то специально настраивать функцию, чтобы указатель на нее был не near, а far?
По-моему, даже есть директива far.


 
афвуд   (2004-01-14 19:02) [35]

Немного не в ту степь.
В Win32 об этом беспокоиться не надо. Это применяется в программировании под ДОС для доступа в другие сегменты памяти.


 
Тимохов   (2004-01-14 19:06) [36]

афвуд © (14.01.04 19:02) [35]
Про 17 строку. Я так понимаю это слэнг многих здесь. Имеется в виду, что ошибка совсем не в том месте, которое обсуждается и без дополнительного углубления в проблематику решить это не выйдет.


 
Ruslan   (2004-01-14 19:38) [37]

Hy я добавлю: может проблема в преобразовании типа процедуры, т.е. когда ты вызываеш процедуру - вместо прямого перехода, она идет по адресу хранящимуся в этой ячейке. Легко проверяется в отладчике.


 
Серега   (2004-01-15 09:22) [38]

Вы чего городите !!!

Программы работают в разных адресных пространствах !!!!


 
alex_***   (2004-01-15 09:24) [39]

Так никто и не спорит с этим...


 
AKul   (2004-01-15 09:44) [40]


> Серега (15.01.04 09:22) [38]
> Вы чего городите !!!
>
> Программы работают в разных адресных пространствах !!!!


Каждый процесс действительно имеет свое адресное пространство.
Но речь вроде бы идет не о разных процессах, а об приложении и DLL, а это одно адрессное пространство (DLL даже может быть промеппирована во все процессы.).



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2004.01.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.009 c
1-93566
snake1977
2004-01-15 17:16
2004.01.29
MDI + DLL


7-93717
Михаил
2003-11-10 16:42
2004.01.29
Кто-нибудь знает как в ХР можно нажимать программно кнопки?


1-93529
Navi
2004-01-17 07:28
2004.01.29
Синхронизировать два StringGrid-а


1-93476
_dEMOn
2004-01-15 20:46
2004.01.29
ListBox.Items


14-93643
Леприкон
2004-01-08 09:01
2004.01.29
Страшное слово...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский