반응형
http://goo.gl/YsesDP




우선 dll 을 만들어 컴파일 하면, 프로젝트명과 동일한 헤더파일, lib 파일, dll 파일이 

생성이 생성되는데...


묵시적으로 dll 을 로드할 경우 위 3개의 파일이 모두 필요 합니다.
(헤더파일이 없어도 되지만, 왜? 헤더까지 필요한지는 아래에 추가로 언급)

dll 의 헤더파일 : 컴파일 할 때 dll 에 있는 함수의 원형을 알아야 한다.
                        -> dll 의 헤더파일이 필요한 이유는 조금 아래에 설명~
dll 의 lib 파일: 링크 시킬 때, dll 에 있는 함수의 몸체(정의부) 를 연결 시켜 실행파일 생성시 필요
                     -> 프로젝트 속성 또는 #pragma comment(lib,,,,) 에서 lib 링크 처리 필요~
dll 파일 : exe 파일이 실행 될 때, dll 에 있는 함수를 호출할 때 필요

->  이 중, 헤더파일, lib 파일은 사용하려는 곳의 소스파일이 있는 폴더에 복사를 시켜두고,
      dll 파일은 exe 실행파일이 있는 곳에 복사를 해 둡니다.


아마. dll 의 헤더파일이 왜?? 필요한가?? 궁금할 텐데...질문한 코드에 보면 묵시적으로 dll 의 함수를
로드할 때,,,

extern "C" __declspec(dllimport) int my_add(int a,int b); 라는 부분이 보입니다.

만약, dll 에서 로드할 함수의 수가 굉장히 많다면, 저 함수들을 사용하는 곳에서 저렇게 일일이 함수 원형 선언을 해주는 것은 노가다 행동일 뿐이죠~

즉, dll 의 헤더파일을 사용하려는 곳에도 복사해주는 이유는 이런 불편함을 줄이기 위함 입니다.

고로, 헤더파일과 cpp 파일을 다음과 같이 수정해 줍니다.

- my_Math.h -

#pragma once

#ifdef DLLEXPORT  // DLLEXPORT 상수가 선언되어 있다면...
#define DLLTYPE __declspec(dllexport)
#else  // 그렇지 않다면...
#define DLLTYPE __declspec(dllimport)
#endif 

extern "C"  DLLTYPE int my_add (int a, int b);

...이하 동일


- my_Math.cpp -


#define  DLLEXPORT  // DLLEXPORT 상수선언 (export  될 것임을 명시하는 부분)

#include "my_Math.h"


extern "C"  DLLTYPE 
int my_add (int a, int b)
{
 .......
}

...이하 동일...



명시적으로 로드할 경우는 위 3개 파일 중에서 dll 파일 하나만 있으면 됩니다.
이 경우, dll 파일 역시, exe 파일이 있는 곳의 폴더에 복사를 해두면 되겠습니다.

일단,,,dll 프로젝트를 빌드하여 lib 파일 dll 파일이 제대로 생성되는지를 본인이 확인해야 합니다.

__declspec(...)  <-- 이 문법에서도 언더바 __ 가 2개 인 것도 확인 하시고...

dll 프로젝트를 빌드하여 제대로 lib, h파일, dll 파일이 생성되었으면 일단 dll 을 사용할 준비가
된 겁니다.

이 생성된 파일들을 위에서 언급한 곳으로 각각 이동을 시킵니다.


- 명시적 실행 소스 코드 -


#include <stdio.h>
#include <windows.h>


// 명시적으로 로드하는 경우, dll 에서 직접 함수의 주소를 읽어 오므로

// 함수의 원형선언 조차도 필요 없습니다.

//_declspec(dllimport) int my_sub(int,int);
//_declspec(dllimport) int my_add(int,int);


typedef int (*ALUFunc)(int,int);


int main()
{
   int a=3,b=5;
   int result;

 ALUFunc my_func ;  //함수 포인터 선언

 HINSTANCE hInstLib = LoadLibrary("___.dll");  // dll 파일명 맞는지 확인할 것 !!

 if (hInstLib == NULL)
{
     printf("오류: DLL을 불러올 수 없습니다\n");
                return 1;
 }
    my_func = (ALUFunc)GetProcAddress(hInstLib,"my_add");

   if (my_func==NULL)
   {
      printf("오류: DLL 함수를 찾을 수 없습니다\n");
                FreeLibrary(hInstLib);
                return 1;

   }

        // 함수 요청하기.
        result = my_func(1, 2);
 
        // DLL 파일의 로드를 해제한다
        FreeLibrary(hInstLib);
 
        // 결과를 보여 준다
        printf("결과는: %f\n", result);

}


=> 특별히 잘못된 부분은 없어 보입니다. LoadLibrary 함수 호출시 dll 파일명이 제대로 되어 있는지
     다시한번 체크를 하는게 좋겠습니다.


- 묵시적 실행 소스 코드 -


#include <stdio.h>

#include "my_Math.h" // dll 의 헤더 포함


#pragma comment(lib, "my_Math.lib")  // 필요한 함수가 어떤 dll 에 있는지 알려주는 역할(링크시 필요)


// dll 의 함수의 원형을 이렇게 하나씩 선언해도 되긴 하지만, 함수의 수가 많아지면

// 이는 굉장히 귀찮은 작업이 됩니다. (my_Math.h 포함하는 것으로 이를 방지함)

/*

extern "C" __declspec(dllimport) int my_add(int a,int b);
extern "C" __declspec(dllimport) int my_sub(int a,int b);
extern "C" __declspec(dllimport) int my_mul(int a,int b);
extern "C" __declspec(dllimport) int my_div(int a,int b);

*/


int main()
{
   int a=3,b=5;

 printf("%d",my_add (a,b));

// return a+b;
 printf("%d",my_sub (a,b));

// return a+b;
 my_mul (a,b);

// return a+b;
my_div (a,b);

 return 0;
}



반응형

+ Recent posts