본문 바로가기

진리는어디에

DLL에서 EXE의 함수 호출하기

들어가며

일반적으로 EXE에서 로드된 DLL의 함수를 호출하는 것은 일반적인 일이다. 하지만 플러그인 프로그램이나 기타 다른 이유로 인해 DLL에서 EXE의 함수를 호출 해야하는 경우가 있다. 이 문서는 그런 경우 유용한 팁을 소개하고 있다. 이 문서는 윈도우에서 DLL을 만들고 로드 하는 방법을 알고 있다는 가정하에 작성 된 것이므로 DLL프로젝트의 생성이나 로드 방법에 대해서는 자세하게 다루지 않는다.

1. 함수를 exporting하는 exe 만들기

exe에서 함수를 export하는 것은 dll에서 하는 그것과 동일한 작업을 하면 된다.

extern "C"
{
  __declspec(dllexport) void ExportFunctionFromEXE(const std::string& callFrom)
  {
    std::cout << "Exe export function called From " << callFrom << std::endl;
  }
}

※ extern "C"

C++스타일 맹글링은 일반 문자열로 표현하기 힘들기 때문에 C스타일의 함수 이름을 노출 하도록 하기 위해 사용 한다. 만일 extern "C" 가 싫다면 .def파일에 노출 하고자 하는 함수의 이름을 적어 주면 된다. 첨부된 예제에서는 .def 파일을 사용하고 있다.

2. 함수를 exporting 하는 DLL 만들기

예제로 소개되는 함수는 exe에의해 호출 되기도 하지만, 동시에 exe에서 export하고 있는 함수를 import 하기도 한다. 파란색으로 하이라이트 표시 되어 있는 GetModuleHandle이라는 함수에게 인자로 NULL을 전달하게 되면 자신이 속한 exe(or 프로세스)의 핸들을 리턴한다. 그 핸들을 이용해 dll에서 import하는 것과 동일하게 exe의 함수를 호출 할 수 있다.

__declspec(dllexport) void ExportFunctionFromDLL(const std::string& callFrom) {
    std::cout << "DLL export function called From " << callFrom << std::endl;
    HINSTANCE hExe = GetModuleHandle(NULL);
    FuncPtrT pFunc = (FuncPtrT)::GetProcAddress(hExe, "ExportFunctionFromEXE");
    if(pFunc)
    {
        (*pFunc)("DLL");
    }
    else
   {
        std::cerr << "Not found proper " << callFrom << " function" << std::endl;
    }
}


3. 결론

결론을 말하자면 함수의 인터페이스를 노출하는 것을 결정하는 것은 파일의 타입이 아니라 코드 내부의 선언이라는 것이다. 우리는 위의 예제에서 exe, dll에 관계없이 함수 인터페이스를 노출 하고 그것을 로드 하는 것을 보았다.

참고적으로 dll에서 exe의 함수를 load 할 때 꼭 같은 프로세스 여야만 한다는 제약도 없다. 위의 GetModuleHandle() 대신 LoadLibrary 함수를 사용하여 load 할 파일에 dll이 아니라 exe파일의 경로를 넘겨 줘도 결과는 같다.

부록 1. 전체 프로젝트 보기

Ref.
 Win32 실행 파일 구조 :

http://quartzd.tistory.com/244

 원문 :

http://www.codeguru.com/Cpp/W-P/dll/article.php/c3649

유익한 글이었다면 공감(❤) 버튼 꾹!! 추가 문의 사항은 댓글로!!