동적 라이브러리의 특징은 해당 라이브러리를 파일로 따로 가지고 있게 만들어져 있다. 해당 라이브러리를 사용하는 프로그램이 실행하는 도중에 해당 파일을 열어서 참조하는 형태로 동적 라이브러리는 작동이 된다.


 쉽게 말해서 프로그램이 특정 기능을 하는 파일을 불러와서 사용하는 것이 동적 라이브러리가 돌아가는 방식이다.


 정적 라이브러리는 해당 프로그램에 링크 과정에서 추가되는 형식이라면, 동적 라이브러리는 해당 프로그램이 실행하는 도중에 호출하는 형식의 차이점을 갖는다.


 정적 라이브러리는 링크 과정에서 해당 프로그램에 기입되는 특징 때문에, 컴파일을 매번 해줘야 된다.

 결국 기능을 수정하게 되면 새로 작성해야된다는 점이. 유동성의 문제점을 가지게 된다.

 반면, 동적 라이브러리는 프로그램이 실행하는 도중에 호출해서 기능을 사용하기 때문에, 호출하는 파일이 변경이 되면 문제가 없다.

 호출 처리를 하는 것으로 파일이 알아서 처리가 되고, 이것은 곧 유동성의 증가가 생기게 된다.


 정적 라이브러리의 단점은 해당 파일에 삽입되는 과정이 있어야되지만, 동적 라이브러리는 해당 파일의 위치를 알게 한다면, 문제가 없어지게 된다.

 이것은 링크과정이 줄게 되는 것이며, 실행하는 도중에 메모리를 먹거나 해제등 복잡해져서 속도가 상대적으로 줄어드는 특징을 가지진다. 그것만 제외하면 제작 시간/개발자의 관리 등에 편의성을 제공한다.


 이전에 작성한 정적 라이브러리의 소스를 그대로 사용할 것이다.


 math.h

1
2
int sum(intint);
int diff(intint);
cs



 math.c

1
2
3
4
5
6
7
8
9
10
11
#include "math.h"
 
int sum(int a, int b)
{
    return a + b;
}
 
int diff(int a, int b)
{
    return a - b;
}
cs


 다음과 같은 명령어를 준다면, 동적 라이브러리가 완성이 된다.


1
gcc -shared -o libmath.so math.c
cs


 이렇게 하면, 동적 라이브러리가 완성이 된다.


 main.c

1
2
3
4
5
6
7
8
9
10
11
12
#include "math.h"
 
int main()
{
    int a = 10;
    int b = 40;
    
    printf("sum : %d\n",sum(a,b));
    printf("diff : %d\n",diff(a,b));
    
    return 0;
}
cs


기존에 있던 방식으로 이렇게 하면, 묵시적 방법으로 라이브러리가 연결이 되어야 된다.


1
gcc -o b main.c .\libmath.so
cs


 이 방법을 사용해서 동적 라이브러리를 연결할 수 있게 되어있다.[각주:1]


 이 외에도 동적 라이브러리는 파일 입출력으로 읽어들어서 기능을 사용할는 방법이 있으며(명시적 호출), 이 방법은 WIndows와 Linux에 따라서 바뀐다.


 Windows에서는 Win32 API을 사용해서 LoadLibrary라는 함수를 사용하게 된다.

 Linux에서는 dlopen이라는 함수가 있다.


 Windows 기준으로 작성을 한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
 
#include <windows.h>
 
int main()
{
    int a = 10;
    int b = 40;
    
    //명시적 연결을 위한 변수.
    HINSTANCE hInstDll;
    int(*sum)(intint);
    int(*diff)(int,int);
    
    hInstDll = LoadLibrary("libmath.so");
    
    sum = (int(*)(int,int))GetProcAddress(hInstDll,"sum");
    diff = (int (*)(intint))GetProcAddress(hInstDll,"diff");
    
    printf("sum : %d\n",(*sum)(a,b));
    printf("diff : %d\n",(*diff)(a,b));
    
    return 0;
}
cs


 여기서, HINSTANCE라는 것은 DLL의 정보를 받기 위해서 설정된 변수이다.

 이 후에 관련 함수의 정보를 가지고 와야하는데, 이 정보는 GetProcAddress을 이요해서 포인트 함수를 받아들여 처리한다.

 여기서, hInstDll가 없을 경우에 없다. 라는 형식으로 작동을 하게 만들 수 있게 된다.


 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
 
#include <windows.h>
 
int main()
{
    int a = 10;
    int b = 40;
    
    //명시적 연결을 위한 변수.
    HINSTANCE hInstDll = NULL;
    int(*sum)(intint);
    int(*diff)(int,int);
    printf("%d\n", hInstDll);
    hInstDll = LoadLibrary("libmath.so");
    printf("%d\n", hInstDll);
    if(hInstDll!=NULL)
    {
        sum = (int(*)(int,int))GetProcAddress(hInstDll,"sum");
        diff = (int (*)(intint))GetProcAddress(hInstDll,"diff");
        
        printf("sum : %d\n",(*sum)(a,b));
        printf("diff : %d\n",(*diff)(a,b));
    }
    
    return 0;
}
cs


이렇게 해서 DLL로 문제 없이 작업이 가능해진다.

  1. 암시적으로 호출 한다. libmath.so가 없을 경우엔 제대로 작동이 되지 않는다. [본문으로]
Posted by JunkMam
,