UNIX 공유객체(shared object) 만들기
테스트 환경을 만들기 전에 파일명을 소개하겠다.
다음은 sotest.cpp
테스트 환경을 만들기 전에 파일명을 소개하겠다.
- Makefile - 빌드를 위한 스크립트
- plgn.cpp - plgn.so를 위한 소스. func2 함수가 포함되어 있다.
- sotest.cpp - 시간 측정을 위한 소스. func1 함수가 포함되어 있다.
TARGET=sotest plgn.so
CXXFLAGS=-g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT
LDFLAGS=-ldl
all:$(TARGET)
clean:
$(RM) $(TARGET) *.o
sotest:sotest.cpp
plgn.so:plgn.o
$(CXX) $(CXXFLAGS) -shared -lc -o $@ $<
plgn.o:plgn.cpp
$(CXX) $(CXXFLAGS) -c -fPIC $<
뭐, 대충 흉내만 내놓고... 다음은 plgn.cppextern "C" void func2(volatile int*);
void
func2(volatile int* v)
{
++(*v);
}
역시나 흉내내기. extern "C"를 붙여 맹글링 회피 능력을 +3 했다. (뻘소리)다음은 sotest.cpp
#include <iostream>
#include <dlfcn.h>
#include <sys/time.h>
using namespace std;
static const size_t testcount(1000000UL);
long long
getTimestamp(void)
{
static struct timeval tv;
gettimeofday(&tv, NULL);
return 1000000LL*tv.tv_sec+tv.tv_usec;
}
extern "C" void func1(volatile int*);
typedef void (*func_t) (volatile int*);
void
func1
(volatile int* i)
{
++(*i);
}
void
testFunc(func_t f, const char* msg)
{
static const long long t1(getTimestamp());
volatile int v(0);
for ( size_t i(0); i<testcount; i++ )
{
f(&v);
}
cout << msg << ": " << (getTimestamp()-t1)/1000.0 << " msec" << endl;
}
void
testSFunc(int flag, const char* msg)
{
static void* handle(NULL);
handle = dlopen("./plgn.so", flag);
if ( !handle )
{
cout << dlerror() << endl;
return;
}
int tip;
func_t f((func_t)dlsym(handle,"func2"));
f(&tip);
testFunc(f, msg);
dlclose(handle);
handle = NULL;
}
int
main(int,char**)
{
testFunc(func1,"Local");
testSFunc(RTLD_LAZY|RTLD_LOCAL, "Shared(LAZY|LOCAL)");
testSFunc(RTLD_NOW|RTLD_LOCAL, "Shared(NOW|LOCAL)");
testSFunc(RTLD_LAZY|RTLD_GLOBAL, "Shared(LAZY|GLOBAL)");
testSFunc(RTLD_NOW|RTLD_GLOBAL, "Shared(NOW|GLOBAL)");
return 0;
}
자, 빌드해보자.$make
g++ -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT -ldl sotest.cpp -o sotest
g++ -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT -c -fPIC plgn.cpp
g++ -g -O2 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT -shared -lc -o plgn.so plgn.o
실행 결과는?$ ./sotest
Local: 3.496 msec
Shared(LAZY|LOCAL): 7.221 msec
Shared(NOW|LOCAL): 10.786 msec
Shared(LAZY|GLOBAL): 14.349 msec
Shared(NOW|GLOBAL): 17.908 msec
느리구나... -_- 두 배나...
댓글
댓글 쓰기