dlopen, dlsym, dlclose, dlerror
함수명 | 매개변수 | 반환값 | 변화 |
---|---|---|---|
void dlopen | (const char *filename, int flag) | NULL (so 파일 존재하지 않거나 로딩 실패 한 경우) | |
NULL 아님 | Shared object 참조 카운트 1 증가 | ||
void dlsym | (void *handle, const char *symbol) | NULL (symbol이 존재하지 않는 경우) | |
NULL 아님 (해당 symbol과 연관된 주소값 반환) | |||
int dlclose | (void* handle) | 0 (정상적으로 close 됨) | |
그 외의 값 (에러 발생 dlerror를 통해 확인 필요) | Shared object 참조 카운트 1 감소 (참조 카운트가 0이되면 메모리에서 삭제) | ||
char* dlerror | (void) | 마지막 발생한 error 메시지 반환 | |
에러 없는 경우 NULL |
사칙연산 기능과 연산 결과를 출력하는 함수를 담은 라이브러리를 작성
해당 라이브러리를 main 프로그램에서 동적으로 적재하여 사용하는 예제
arith.hpp : 함수 선언을 담은 파일
arith_func1.cpp : 사칙 연산 함수 구현
libarith.so : 위 파일을 --shared 옵션을 통해 만든 공유 라이브러리 파일
main.cpp : libarith.so 공유 라이브러리 파일을 런타임 참조하도록 작성한 파일
// arith.hpp
#ifndef ARITH_HPP
#define ARITH_HPP
extern "C" {
int add(int a, int b);
int sub(int a, int b);
int divv(int a, int b);
int mul(int a, int b);
void printall(int a, int s, int d, int m);
}
#endif
// arith_func1.cpp
#include "arith.hpp"
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
// arith_func2.cpp
#include <stdio.h>
#include "arith.hpp"
int divv(int a, int b) {
return a/b;
}
int mul(int a, int b) {
return a*b;
}
void printall(int a, int s, int d, int m) {
printf("Add: %d, sub: %d, Div: %d, Mul: %d\\n", a, s, d, m);
}
// main.cpp
#include <iostream>
#include <dlfcn.h>
using namespace std;
int main (int argc, char** argv) {
int a, b;
cout << "Input the Number (a/b) : ";
cin >> a >> b;
cout << "C++ dlopen demo running~~~~ \\n\\n\\n";
cout << "Opening libarith.so.....\\n\\n";
void* handle = dlopen("./libarith.so", RTLD_NOW);
// handle을 통해 라이브러리 파일 위치의 주소값을 넘겨 받음.
// RTLD_NOW는 dlopen() 함수 호출과 동시에 load
if(handle==0) {
cerr << "Cannot open library : " << dlerror() << endl;
return 1;
}
cout << "Loading symbol arith.... \\n\\n";
typedef int (*add_t)(int, int);
typedef int (*sub_t)(int ,int);
typedef int (*divv_t)(int ,int);
typedef int (*mul_t)(int, int);
typedef void (*printall_t)(int, int, int, int);
add_t add = (add_t) dlsym(handle, "add");
sub_t sub = (sub_t) dlsym(handle, "sub");
divv_t divv = (divv_t) dlsym(handle, "divv");
mul_t mul = (mul_t) dlsym(handle, "mul");
printall_t printall = (printall_t) dlsym(handle, "printall");
if(printall == 0) {
cerr << "Cannot load symbol 'arith' : " << dlerror() << endl;
dlclose(handle);
return 1;
}
cout << " Calling arith..\\n\\n";
printall(add(a, b), sub(a, b), divv(a, b), mul(a, b));
cout << "Closing library...\\n\\n";
dlclose(handle);
return 0;
}
Makefile
arith_func1.o: arith.hpp arith_func1.cpp
g++ -c arith_func1.cpp -fPIC
arith_func2.o: arith.hpp arith_func2.cpp
g++ -c arith_func2.cpp -fPIC
libarith.so: arith.hpp arith_func1.o arith_func2.o
g++ -shared -o libarith.so arith_func1.o arith_func2.o
main: arith.hpp main.cpp libarith.so
g++ -o main main.cpp -ldl
all : main
clean :
rm -f arith_func1.o arith_func2.o libarith.so main