在C++中载入库文件


在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;
};

#endif


testLib.h文件
#ifndef TESTLIB_H
#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 ;
}

然后进行编译链接得到动态库
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 ;
}

然后编译链接:
g++ -ldl main.cpp -o test
-ldl选项是要调用libdl.so库,这个库中有dlfcn.h头文件中的函数
运行结果如下:
TestLib::init:Hello World!!


posted @ 2012-04-26 17:34  Mr.Rico  阅读(2081)  评论(0编辑  收藏  举报