• Loginov Dmitry © (16.07.08 17:56) [0]
    Весь моск сломал, пока разобрался в чем ошибка.

    Вот (псевдо)код из EXE:


    procedure MyProc;
    var
     H: Cardinal;
     Proc: procedure;  
    begin
     H := LoadLibrary('mydll.dll');
     if H <> 0 then
     begin
       Proc := GetProcAddress(H, 'Proc');
    if Assigned(Proc) then
    try
      Proc();
    except
      on E: Exception do
      begin
        ShowMessage(E.Message); // показываем пользователю ошибку
        FreeLibrary(H); // выгружаем библиотеку (от нее никакой пользы уже нет)  
      end;
    end;
     end;
    end;



    Код процедуры в DLL


    type
     EMyException = class(Exception);
     
    procedure Proc;
    begin
     raise EMyException.Create('Ошибка при работе функции Proc');
    end;



    Вопрос: почему при вызове функции MyProc выдается ошибка:
    Access violation at address 20006F8C in module 'rtl100.bpl'. Read of address 00000000 (EAccessViolation)



    Ответ оказался слишком простым, поэтому сообщу позже (желающие могут сами разобраться, все необходимое я привел). Интересно, кому нибудь приходилось разбираться с такими приколами? ;)
  • Loginov Dmitry © (16.07.08 17:59) [1]
    Блин, Notepad++ съел все форматирование :(


    procedure MyProc;
     var
       H: Cardinal;
       Proc: procedure;
    begin
       H := LoadLibrary('mydll.dll');
       if H <> 0 then
       begin
         Proc := GetProcAddress(H, 'Proc');
         if Assigned(Proc) then
         try
           Proc();
         except
           on E: Exception do
           begin
             ShowMessage(E.Message); // показываем пользователю ошибку
             FreeLibrary(H); // выгружаем библиотеку (от нее никакой пользы уже нет)
           end;
         end;
       end;
    end;

  • wl © (16.07.08 18:10) [2]
    что-то типа для передачи строк из dll в exe нужно подключить некий модуль?
  • Поросенок Винни-Пух © (16.07.08 18:13) [3]
    потому что возбуждено в длл, а обращение к строке идет в хост аппликейшен (а шаремема нет)

    Exception = class(TObject)
    .....
    property Message: string read FMessage write FMessage;
  • Ega23 © (16.07.08 18:21) [4]
    Я бы ErrorCode из Dll возвращал, а не исключение генерил.
    Но это так, к слову...
  • Mystic © (16.07.08 18:27) [5]
    Потому что в DLL своей класс Exception, а в твоем приложении свой.
  • Dimka Maslov © (16.07.08 19:03) [6]
    Можно ещё попробовать сгенерировать исключение в библиотеке, написанной на С.
  • Loginov Dmitry © (16.07.08 19:18) [7]
    > что-то типа для передачи строк из dll в exe нужно подключить
    > некий модуль?



    > Потому что в DLL своей класс Exception, а в твоем приложении
    > свой.


    И EXE и DLL скомпилированы с runtime-пакетами :)
  • Loginov Dmitry © (16.07.08 19:19) [8]
    ShowMessage(E.Message);
    отрабатывает верно, показывает что и должно. Ошибка возникает после.
  • @!!ex © (16.07.08 19:22) [9]
    > скомпилированы с runtime-пакетами :)

    тото ошибка в RTL(Run Time Library) вылазит.
  • Loginov Dmitry © (16.07.08 19:35) [10]
    Еще:
    если заменить
    raise EMyException.Create('Ошибка при работе функции Proc');


    на
    raise Exception.Create('Ошибка при работе функции Proc');



    то AV не возникает (это поведение как раз и позволило понять что именно происходит :)
  • Loginov Dmitry © (16.07.08 20:41) [11]
    Весь прикол в следующем:

    Класс
    EMyException = class(Exception);

    объявлен в DLL (а не в runtime-пакете), в связи с этим в DLL расположен код, учавстующий в процессе уничтожения объекта. При вызове
    FreeLibrary(H);

    этот код выгружается вместе в DLL. При отсутствии кода регенерации исключения в блоке
    except..end

    происходит неявное уничтожение объекта исключения. При этом естественно возникнет AV, т.к. кода, ответственного за уничтожение объекта, уже нет.

    P.S. данный вывод сделан без анализа ассемблерного кода, если в чем-то неправ, то поправьте.
  • www (16.07.08 21:05) [12]
    ну так разные классы, один из которых пытается пролезть в ехе, а в ехе он не описан
Есть новые Нет новых   [134439   +46][b:0][p:0.002]