Re: вызов функции из длл на дельфи (и исключения при этом )
От: SchweinDeBurg Россия https://zarezky.spb.ru/
Дата: 13.05.04 19:08
Оценка: +2
Здравствуйте, Lecha, Вы писали:

L>Приветствую,

L>такая вот проблема:
L>есть dll на дельфи (без исходников), листочек документации к ней(прототипы функций) и небольшой примерчик тоже на дельфи, который эту dll вызывает.

L>//прототип из документации

L>procedure connect(hostName, portNumber: PChar); stdcall; external CustomDll;

L>
L>//кусок из примерчика
L>...
L>begin
L>try
L>connect(PChar(EditHost.Text), PChar(EditPort.Text));
L>except
L>On E: Exception do
L>begin
L>S := getExceptionInfo(E); //see below
L>writeln(S);
L>raise Exception.Create(S);
L>end;
L>end;
L>end;

L>//там же из примечика
L>function getExceptionInfo(E: Exception): PChar;
L>var
L>S: String;
L>buf: array[0..512] of char;
L>begin
L>S := E.ClassName + ', ' + E.Message;
L>StrLCopy(buf, PChar(S), SizeOf(buf));
L>Result := buf;
L>end;
L>


L>все работает замечательно (примерчик на дельфи то есть), когда правильные параметры даешь(адрес и порт) то просходит коннект, если же неправильные — генерится исключение (таймаут) и красиво пишется как в консольное окошко так и в мевсседжбокс.


Что естественно — исключение Object Pascal ловится кодом Object Pascal.

L>Теперь мне надо позвать эту функцию из VC++ 6.0 (и исключения обработать)

L>мой код:

L>
L>...
L>try
L>{
L>// call the function
L>   pconnect (_T("aaa"),_T("bbb"));
L>}
L>catch(CException * e)
L>{
L>   e->>ReportError();
L>   e->>Delete();
L>}
L>


L>вроде выглядит нормально,(хандле от длльки и указатель на функцию валидные),

L>но при выполнениии "unchandled exception" (причем в обоих случаях, т.е когда правильные и когда неправильные параметры)
L>получается , что CException и все порожденные мы не ловим.

Совершенно верно — MFC-шный CException к дельфийскоу Exception никакого отношения не имеет.

L>
L>// меняю catch блок на
L>catch(...)
L>{
L>ASSERT(FALSE);
L>}
L>


L>теперь нормально, попадаю в catch, но никакойиформации об исключении получить нельзя (а может можно? как?)


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

L>пробовал применитиь структурную систему


L>
L>//вот так примерно
L>DWORD FilterFunction(LPEXCEPTION_POINTERS pe) 
L>{ 
L>ASSERT(pe->ExceptionRecord->ExceptionCode);
L>return EXCEPTION_EXECUTE_HANDLER; 
L>} 
L>.....

L>__try
L>{
L>// call the function
L>pconnect (_T("aaa"),_T("bbb"));
L>}
L>__except ((FilterFunction(GetExceptionInformation()))
L>{
L>ASSERT(FALSE); 
L>}

L>


L>также ловится( точка останова на return EXCEPTION_EXECUTE_HANDLER; )

L>при этом
pe->>ExceptionRecord->ExceptionCode = 0x0eedfade (стабильно)

Знакомое число какое-то... а что при этом в окошке отладчика написано?

L>и

pe->>ExceptionRecord->NumberParameters=7;
pe->>ExceptionRecord->ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]также семь заполнено

L>проблема в том что имею предубеждение к дельфям, поэтому не ориентируюсь там совсем,


А вот это зря — "врагов нужно изучать"! (большая просьба ко всем — не цепляться к слову "враги" и не начинать флейм на тему "C++ vs. Delphi ).

L>stdcall в дельфях имеет другой смысл? PChar это не LPTSTR?

Нет, это там такое же, разве что декорация имен может отличаться от MSVC. И PChar это скорее все-таки LPSTR (без T).

L>у кого какие идеи?


ИМХО, самое надежное (чтобы без хакерства и асма) — написать на Delphi еще одну DLL, которая будет выполнять роль заглушки, вызывая бросающий исключения код, отлавливая эти исключения и передавая информацию о них "наверх" в гарантированно совместимой форме (в самодельной структуре, например... WNDCLASS — он-то везде WNDCLASS, что у "них", что у нас). И уже эту заглушку дергать из плюсового кода.
[ posted via RSDN@Home 1.1.2 stable ]
- Искренне ваш, Поросенок Пафнутий
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.