15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Упростим загрузку DLL


Автор: Shoalin Panda

Описание

Обычно Dynamic Link Librarys загружают следующим способом: LoadLibrary, и GetProcAddress затем проверяют, чтобы адрес каждой функции не был NULL, приведение указателя функции и т.д. Всё это конечно утомительно, но, оказывается есть более простой способ совладать с DLL-ками.

 

//GetProcAddresses
//Argument1: hLibrary - Обработчик загружаемой библиотеки
//Argument2: lpszLibrary - Загружаемая библиотека
//Argument3: nCount - Количество загружаемых функций
//[Arguments Format]
//Argument4: Function Address - Адрес функции
//Argument5: Function Name -  Желаемое для нас имя функции
//[Repeat Format]
//
//Returns: FALSE if failure
//Returns: TRUE if successful
BOOL GetProcAddresses(HINSTANCE *hLibrary,LPCSTR lpszLibrary,INT nCount,...)
{
   va_list va;
   va_start( va, nCount );

   if ( ( *hLibrary = LoadLibrary( lpszLibrary ) ) != NULL )
   {
      FARPROC * lpfProcFunction = NULL;
      LPSTR lpszFuncName = NULL;
      INT nIdxCount = 0;
      while ( nIdxCount < nCount )
      {
         lpfProcFunction = va_arg( va, FARPROC* );
         lpszFuncName = va_arg( va, LPSTR );
         if ( ( *lpfProcFunction = GetProcAddress( *hLibrary,
                                             lpszFuncName ) ) == NULL )
         {
            lpfProcFunction = NULL;
            return FALSE;
         }
         nIdxCount++;
      }
   }
   else
   {
      va_end( va );
      return FALSE;
   }
   va_end( va );
   return TRUE;
}

Итак, теперь можно в функции main посмотреть, как это работает ( компилировалось как консольное приложение )

#include 

typedef int ( WINAPI *MESSAGEBOX ) ( HWND , LPCSTR, LPCSTR, DWORD );
typedef int ( WINAPI *MESSAGEBOXEX ) (HWND , LPCSTR, LPCSTR, DWORD , WORD);

void main(void)
{
   MESSAGEBOX lpfMsgBox = NULL;
   MESSAGEBOXEX lpfMsgBoxEx = NULL;
   HINSTANCE hLib;
   if(GetProcAddresses( &hLib, "User32.dll", 2,
                        &lpfMsgBox, "MessageBoxA",
                        &lpfMsgBoxEx, "MessageBoxExA" ) )
   {
       lpfMsgBox( 0, "Test1", "Test1", MB_OK );
       lpfMsgBoxEx( 0, "Test2", "Test2", MB_OK, MAKELANGID( LANG_ENGLISH,
                                                     SUBLANG_ENGLISH_US ) );
   }
   if ( hLib != NULL )
      FreeLibrary( hLib );
}

Вот собственно и всё.