[cpp] GetProcAddress를 편리하게 사용하는 방법

@codemaru · June 17, 2015 · 3 min read

윈도우의 경우 9x와 NT 계열의 함수 세트가 틀린 경우가 있다. 9x에만 존재하는 함수가 있는가 하면, NT에만 존재하는 함수도 있다. 이러한 경우 한 프로그램이 두가지 환경에서 모두 동작해야 하는 경우에 주로 LoadLibrary를 사용해서 해당 함수들을 동적으로 불서서 사용한다. 물론 그 외에도 동적으로 불러쓰는 경우는 매우 많다.

이렇게 LoadLibrary를 통해서 함수를 불러 쓸 때 가장 불편한 점은 함수 포인터를 반환받는 과정이다. 함수 하나하나 마다 모두 GetProcAddress로 함수 포인터를 받아야 하기 때문이다. 이러한 과정을 좀 더 간소화 시킬 수 없을까? 여기에 대한 답이 www.codeproject.com에 나와있다. 바로 가변 인자를 사용한 방법이다. 아래 함수는 실제 원문에 있던 함수를 약간 수정한 버전이다. 출구를 하나로 통일하고, 함수 로드에 실패한 경우에는 항상 DLL을 언로드 하도록 변경했다. 실제 원문은 http://www.codeproject.com/dll/dllease.asp 에서 확인할 수 있다.

GetProcAddresses 소스 코드 다운로드

BOOL GetProcAddresses( HINSTANCE *hLibrary, LPCSTR lpszLibrary, INT nCount, ... )
{
    BOOL bRet = TRUE;
    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;
                bRet = FALSE;
                break;
            }
            nIdxCount++;
        }
    }
    else
    {
        bRet = FALSE;
    }
    va_end( va );
    
    if(bRet == FALSE && *hLibrary != NULL)
        FreeLibrary(*hLibrary);
    
    return bRet;
}

사용하는 방법은 무척이나 간단하다. 첫번째 인자로 리턴받을 DLL인스턴스 핸들을, 두번째 인자로 DLL 파일명을, 세번째 인자로 로드할 함수 갯수를, 그 다음부터는 함수 포인터의 포인터와, 함수명을 교대로 적어주면 된다. 말로하니 매우 복잡한데, 실제 사용예를 보면 금방 알 수 있다. 아래는 kernel32.dll에서 CreateFileW와 CloseHandle 함수를 로드하는 방법을 보여준다.

HINSTANCE hinst;
GetProcAddresses(&hinst, "kernel32.dll", 2, 
                 &fnCreateFileW, "CreateFileW", 
                 &fnCloseHandle, "CloseHandle");
@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중