在C语言中载入库比较容易,而在C++中则比较麻烦。在C语言中函数都唯一的,这样在库中可以直接使用函数名作为函数的记号,而在C++中由于函数重载和多态的存在,使得C++中函数名不能直接作为函数的记号。为了解决这个问题,C++中使用是Name mangling技术,对不同的函数映射得到一个唯一的记号。可以看维基百科的介绍:http://en.wikipedia.org/wiki/Name_mangling
为了能直接使用函数名作为记号,可以在C++中将函数声明为C的形式,最常见的做法即:使用extern “C”。
下面我们演示一下使用extern的情况下的在C++中载入库:
testVir.h文件
#ifndef TESTVIR H
#define TESTVIR_H
class TestVir
{
public:
virtual void init()=0;
};
#define TESTVIR_H
class TestVir
{
public:
virtual void init()=0;
};
#endif
testLib.h文件
#ifndef TESTLIB_H
#define TESTLIB_H
class TestLib:public TestVir
{
public:
void init();
};
#define TESTLIB_H
class TestLib:public TestVir
{
public:
void init();
};
#endif
testLib.cc文件:
#include <iostream>
#include "testVir.h"
#include "testLib.h"
using namespace std;
void TestLib::init()
{
cout<<"TestLib::init: Hello World!! "<<endl ;
}
//Define functions with C symbols (create/destroy TestLib instance).
extern "C" TestLib* create()
{
return new TestLib;
}
extern "C" void destroy(TestLib* Tl)
{
delete Tl ;
}
#include "testVir.h"
#include "testLib.h"
using namespace std;
void TestLib::init()
{
cout<<"TestLib::init: Hello World!! "<<endl ;
}
//Define functions with C symbols (create/destroy TestLib instance).
extern "C" TestLib* create()
{
return new TestLib;
}
extern "C" void destroy(TestLib* Tl)
{
delete Tl ;
}
然后进行编译链接得到动态库
g++ -shared -fPIC testLib.cpp -o testLib.so
然后建立main.cc文件,调用其中的函数:#include<iostream>
#include<dlfcn.h>
#include "testVir.h"
using namespace std;
int main()
{
void *handle;
handle = dlopen("./testLib.so", RTLD_NOW);
if (!handle)
{
printf("The error is %s", dlerror());
}
typedef TestVir* create_t();
typedef void destroy_t(TestVir*);
create_t* creat=(create_t*)dlsym(handle,"create");
destroy_t* destroy=(destroy_t*)dlsym(handle,"destroy");
if (!creat)
{
cout<<"The error is %s"<<dlerror();
}
if (!destroy)
{
cout<<"The error is %s"<<dlerror();
}
TestVir* tst = creat();
tst->init();
destroy(tst);
return 0 ;
}
#include<dlfcn.h>
#include "testVir.h"
using namespace std;
int main()
{
void *handle;
handle = dlopen("./testLib.so", RTLD_NOW);
if (!handle)
{
printf("The error is %s", dlerror());
}
typedef TestVir* create_t();
typedef void destroy_t(TestVir*);
create_t* creat=(create_t*)dlsym(handle,"create");
destroy_t* destroy=(destroy_t*)dlsym(handle,"destroy");
if (!creat)
{
cout<<"The error is %s"<<dlerror();
}
if (!destroy)
{
cout<<"The error is %s"<<dlerror();
}
TestVir* tst = creat();
tst->init();
destroy(tst);
return 0 ;
}
然后编译链接:
g++ -ldl main.cpp -o test
-ldl选项是要调用libdl.so库,这个库中有dlfcn.h头文件中的函数运行结果如下:
TestLib::init:Hello World!!