На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела Visual C++ / MFC / WTL (далее Раздела)
1) На Раздел распространяются все Правила Форума.
2) Перед тем, как создать новый топик, убедитесь, что Вы читали Правила создания тем в Разделе.
3) Вопросы, не связанные с программированием (настройки MS Visual Studio, книги, библиотеки и т.д.),
обсуждаются в разделе C/C++: Прочее
4) Вопросы разработки .NET (Windows Form, C++/CLI и т.п.) приложений на Visual C++/C# обсуждаются в разделе .NET.
5) Нарушение Правил может повлечь наказание со стороны модераторов.

Полезные ссылки:
user posted image FAQ Раздела user posted image Обновления для FAQ Раздела user posted image Поиск по Разделу user posted image MSDN Library Online
Модераторы: ElcnU
  
> Как использовать GetProcAddress()
    Покажите плз. как правильно воспользоваться функциями LoadLibrary(),GetProcAddress() и FreeLibrary().
    Вот мой пример:
    Простая библиотека DLL, вот что в ней
    ExpandedWrap disabled
      class __declspec(dllexport) TestFunction
      {
      public:
          TestFunction(void);
          virtual ~TestFunction(void);
      public:
          int MyFunction(int myArrea[]);
      };
      TestFunction::TestFunction(void)
      {
      }
       
      TestFunction::~TestFunction(void)
      {
      }
       
      TestFunction::MyFunction(int myArrea[])
      {
      int summ;
      for(int i=0;i<sizeof(myArrea);i++)
      {
      summ=summ+myArrea[i];
      }
      return summ;
      }

    Скомпонована в файл TestDll1_1.dll.

    Теперь я хочу воспользоваться этим классом из диалогового приложения.
    Вот часть кода диалогового приложения где мне нужно воспользоваться объектом DLL и вычислить сумму. Допишите ПЛЗ! код, а то я чет не совсем понял как та делать нужно.
    ExpandedWrap disabled
      void CtestDll1_2Dlg::OnBnClickedButton2()
      {
          HINSTANCE hMyDLL;
          if((hMyDLL=::LoadLibrary("TestDll1_1")==NULL)
          {
          AfxMessageBox("Не удалось загрузить DLL");
          }
          else
          {
      //У меня здесь есть числовой массив myArrea_x,
      //как мне определить сумму всех его элементов,
      //при этом используя функцию класса
      //TestFunction:: MyFunction(int myArrea[]);
          }
      }
      Пример из MSDN

      ExpandedWrap disabled
        // File:  RUNTIME.C
        // A simple program that uses LoadLibrary and
        // GetProcAddress to access myPuts from MYPUTS.DLL.
         
        #include <stdio.h>
        #include <windows.h>
         
        typedef VOID (*MYPROC)(LPTSTR);
         
        VOID main(VOID)
        {
            HINSTANCE hinstLib;
            MYPROC ProcAdd;
            BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
         
            // Get a handle to the DLL module.
         
            hinstLib = LoadLibrary("myputs");
         
            // If the handle is valid, try to get the function address.
         
            if (hinstLib != NULL)
            {
                ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts");
         
                // If the function address is valid, call the function.
         
                if (fRunTimeLinkSuccess = (ProcAdd != NULL))
                    (ProcAdd) ("message via DLL function\n");
         
                // Free the DLL module.
         
                fFreeResult = FreeLibrary(hinstLib);
            }
         
            // If unable to call the DLL function, use an alternative.
         
            if (! fRunTimeLinkSuccess)
                printf("message via alternative method\n");
        }
        А можно на моем примере показать :o
          Что не ужеле так сложно, или наоборот слишком легко?
          Если кто может покажите на моем примере, не как не могу понять как правильно воспользоваться GetProcAddress() :wall:
            Цитата maxNTF @
            Покажите плз. как правильно воспользоваться функциями LoadLibrary(),GetProcAddress() и FreeLibrary().
            Вот мой пример:
            Простая библиотека DLL, вот что в ней
            ExpandedWrap disabled
              class __declspec(dllexport) TestFunction
              {
              public:
                  TestFunction(void);
                  virtual ~TestFunction(void);
              public:
                  int MyFunction(int myArrea[]);
              };
              TestFunction::TestFunction(void)
              {
              }
               
              TestFunction::~TestFunction(void)
              {
              }
               
              TestFunction::MyFunction(int myArrea[])
              {
              int summ;
              for(int i=0;i<sizeof(myArrea);i++)
              {
              summ=summ+myArrea[i];
              }
              return summ;
              }

            Скомпонована в файл TestDll1_1.dll.

            Теперь я хочу воспользоваться этим классом из диалогового приложения.
            Вот часть кода диалогового приложения где мне нужно воспользоваться объектом DLL и вычислить сумму. Допишите ПЛЗ! код, а то я чет не совсем понял как та делать нужно.
            ExpandedWrap disabled
              void CtestDll1_2Dlg::OnBnClickedButton2()
              {
                  HINSTANCE hMyDLL;
                  if((hMyDLL=::LoadLibrary("TestDll1_1")==NULL)
                  {
                  AfxMessageBox("Не удалось загрузить DLL");
                  }
                  else
                  {
                      ProcAdd = (MYPROC) GetProcAddress(hinstLib, "MyFunction");
                      if (fRunTimeLinkSuccess = (ProcAdd != NULL))
                          (ProcAdd) (MyArr[]);
                      fFreeResult = FreeLibrary(hinstLib);
                  }
               
                  }
              }

            см.
              Какой мне нужно указать тип указателя принимающий функцией MyFunction()?
              int что ли? Типа так?
              ExpandedWrap disabled
                typedef int (*MYPROC)(int);
                ExpandedWrap disabled
                  int MyFunction(int myArrea[]);

                У тебя всетаки там массив! ;)
                  У имён функций классов будут, скорее всего, какие-нибудь страшные имена. Лучше сделать примерно так:
                  ExpandedWrap disabled
                    class TestFunctionInterface {
                        virtual int MyFunction(int myArrea[]) = 0;
                        virtual void Release() = 0;
                    };
                     
                     
                    class TestFunction: public TestFunctionInterface
                    {
                    public:
                        TestFunction(void);
                        virtual ~TestFunction(void);
                    public:
                        virtual int MyFunction(int myArrea[]);
                        virtual void Release();
                    };
                    TestFunction::TestFunction(void)
                    {
                    }
                     
                    TestFunction::~TestFunction(void)
                    {
                    }
                     
                    TestFunction::MyFunction(int myArrea[])
                    {
                    int summ;
                    for(int i=0;i<sizeof(myArrea);i++)
                    {
                    summ=summ+myArrea[i];
                    }
                    return summ;
                     
                    void TestFunction::Release() {
                         delete this;
                    }
                     
                    }


                  И добавить в библиотеку функцию типа
                  ExpandedWrap disabled
                    TestFunctionInterface * MakeTestFunction() {
                        return new TestFunction;
                    }


                  В программе, которая использует библиотеку, написать так:
                  ExpandedWrap disabled
                    HINSTANCE dll = LoadLibrary("TestDll1_1");
                    if(dll) {
                        typedef TestFunction * (*MakeFunc)();
                        MakeFunc func = (MakeFunc)GetProcAddress(dll, "MakeTestFunction");
                        if(func) {
                            TestFunction * test = (func)();
                            int sum = test->MyFunction(arr);
                            // ...
                            test->Release();
                        } else {
                            // ...
                        }
                    } else {
                        // ...
                    }


                  Добавлено
                  Ещё, функцию MakeTestFunction сделать так:
                  ExpandedWrap disabled
                    TestFunctionInterface * __stdcall MakeTestFunction() {
                        return new TestFunction;
                    }

                  и запихать её ещё в def файл.
                  Сообщение отредактировано: Sanek -
                    Чет я совсем дубовый.
                    Плиз подправьте мой пример, чтоб переменной summ (класса CtestDll1_2Dlg) присваивалось значение возвращающее функцией MyFunction()(из файла TestDll1_1.dll)
                    Ниже прикрепляю то, что я тут наваял, но оно не работает.
                    Прикреплённый файлПрикреплённый файлTestDLL.rar (64.46 Кбайт, скачиваний: 323)
                      Твой пример править не стал, там MFC, какие-то ошибки выдаёт.
                      Сделал пример. В функцию ещё надо передавать количество элементов, потому как sizeof ты их не определишь.
                      Работать то работает. Вот только я не понимаю, нафига? Если тебе надо создавать классы с одними и теми же интерфейсами из разных библиотек, то можно и без GetProcAddress обойтись. Просто каждая библиотека должна содержать определённую функцию.
                      Прикреплённый файлПрикреплённый файлdll_class.zip (7.8 Кбайт, скачиваний: 372)
                        Пример из #10 точно заработает если dll положить в директорию к exe или прописать путь, типа:
                        HMODULE lib = LoadLibrary(TEXT("..\\..\\dll\\Release\\dll"));
                        0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                        0 пользователей:


                        Рейтинг@Mail.ru
                        [ Script execution time: 0,0424 ]   [ 17 queries used ]   [ Generated: 29.03.24, 07:50 GMT ]