На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
  
> Ошибка в DLL при попытке обратиться к переменной, созданной в другой DLL. , XE7, Win7
    Простой тест: в главной программе загружаются две DLL. В первой DLL создаётся объект, а во второй - Access violation при попытке к нему обратиться.
    ExpandedWrap disabled
      //  главная программа
      typedef void __stdcall (*TFuncFH)(int *fh);
      //...
      void __fastcall TForm1::button1Click(TObject *Sender)
      {
        HMODULE hnd1 = LoadLibrary(L"Lib1.dll");
        HMODULE hnd2 = LoadLibrary(L"Lib2.dll");
        int *fh;
        ((TFuncFH)GetProcAddress(hnd1, "Open_FH"))(fh);
        ((TFuncFH)GetProcAddress(hnd2, "Close_FH"))(fh);
      }
       
      //  Lib1.dll
      extern "C" __declspec(dllexport) void __stdcall Open_FH(int *fh);
      //...
      void __stdcall Open_FH(int *fh)
      {
        fh = new int;
        *fh = FileOpen(L"Test.txt", fmOpenWrite);
      }
       
      //  Lib2.dll
      extern "C" __declspec(dllexport) void __stdcall Close_FH(int *fh);
      //...
      void __stdcall Close_FH(int *fh)
      {
        FileClose(*fh);       //  Access violation !!!
        delete fh;
      }

    Почему так получается, несмотря на одно адресное пространство?
      Потому что фигню написал, потому и Access Violation.
      Ты в Close_FH() передаёшь мусор.
      fh не инициализирован, и Open_FH() её значение тоже никак не меняет (ты видимо ожидаешь другого).
      А вообще люди отладчики придумали...
        Цитата cppasm @
        Ты в Close_FH() передаёшь мусор.fh не инициализирован, и Open_FH() её значение тоже никак не меняет (ты видимо ожидаешь другого).
        А почему тогда, если создаю объект fh (fh = new int;) в главной программе, то всё работает? Какая разница, где создавать объект, если это одно адресное пространство?

        Цитата cppasm @
        Потому что фигню написал, потому и Access Violation.
        Здорово, а я думал, что всё правильно.

        Цитата cppasm @
        А вообще люди отладчики придумали...
        Ну да. Только не для всего, например, для XE7 C++Builder 64bit отладчик не работает, о чём честно сообщил в своё время Embarcadero.
          Цитата vlad2 @
          А почему тогда, если создаю объект fh (fh = new int;) в главной программе, то всё работает?

          Ok, встречный вопрос:

          ExpandedWrap disabled
            #include<stdio.h>
             
            void bug_set_3(int arg)
            {
              arg=3;
            }
             
            int main(int argc, char *argv[])
            {
              int x=1;
              bug_set_3(x);
              printf("%d\n", x);
              return 0;
            }

          Что будет выведено и почему?
          Думаю это долно пролить свет на твою проблему.
          Сообщение отредактировано: cppasm -
            Цитата
            если создаю объект fh (fh = new int;)


            смотри пример:

            ExpandedWrap disabled
              int *a = new int;
              a = 1; // a = 1 да?
               
              int *b = a;
              b = new int;
              b = 2; // по твоему, станет a = 2?


            Посмотри на свой код внимательнее.

            Добавлено
            Цитата
            Что будет выведено и почему?

            Блин, у меня более толсто получилось :D
              Цитата vlad2 @
              Ну да. Только не для всего, например, для XE7 C++Builder 64bit отладчик не работает, о чём честно сообщил в своё время Embarcadero.

              Тогда это вечная пытка. :(
              Используй OutputDebugString + DbgView.
              ссылка
                Цитата ЫукпШ @
                Используй OutputDebugString + DbgView.

                Я может чего не понимаю, но в чём проблема собрать в 32 бита, отладить, а потом пересобрать релиз в 64 бита?
                  Цитата cppasm @
                  Цитата ЫукпШ @
                  Используй OutputDebugString + DbgView.

                  Я может чего не понимаю, но в чём проблема собрать в 32 бита, отладить, а потом пересобрать релиз в 64 бита?

                  Ни в чём. Это можно, однозначно.
                  Но не уверен, что удобно.
                  Между x86 и x64 могут быть тонкости на уровне исходных текстов.
                  Поэтому всегда неплохо делать обе сборки. Обычно я так и делаю.
                  Ограничивать одну из них я бы не стал.
                  Сообщение отредактировано: ЫукпШ -
                    Цитата ЫукпШ @
                    Между x86 и x64 могут быть тонкости на уровне исходных текстов.

                    Это да, но косяки как в первом посте к тонкостям не относятся и в отладчике выловить было бы просто ))
                      Цитата cppasm @
                      Думаю это долно пролить свет на твою проблему.

                      Цитата VisualProg @
                      Посмотри на свой код внимательнее
                      Ну да, спасибо, & - ссылочку забыл.

                      Цитата ЫукпШ @
                      Используй OutputDebugString + DbgView.
                      Спасибо за ссылку.

                      Цитата ЫукпШ @
                      Между x86 и x64 могут быть тонкости на уровне исходных текстов.
                      Да, и не только. Дело осложняется ещё тем, что мои проги активно используют чужие 64 битные длл-ки.
                        Цитата vlad2 @
                        Ну да, спасибо, & - ссылочку забыл.

                        Да, или ссылку надо использовать, или указатель на указатель.
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0387 ]   [ 16 queries used ]   [ Generated: 23.04.24, 12:26 GMT ]