如何在C++中使用共享库的动态加载

一、先看看测试程序

1.库部分

hello.h

#ifndef ANDROID_Hello_H
#define ANDROID_Hello_H
class Hello_Base
{
  public:
    virtual ~Hello_Base() {};
    virtual int setctl(int ctl) = 0;
    virtual int getctl(int ctl) = 0;
};

class Hello : public virtual Hello_Base
{
  public:
    virtual ~Hello() {};
    static Hello* Instance();
    int setctl(int ctl);
    int getctl(int ctl);

  private:
    static Hello* _instance;
    int myctl;
};

extern "C" Hello_Base* CreatHello();
typedef Hello_Base* CreatHelloClass();

#endif
hello.cpp
#include "hello.h"
#include <stdio.h>
extern "C" Hello_Base* CreatHello(){
  return Hello::Instance();
}



Hello* Hello::_instance = 0;

Hello* Hello::Instance()
{
  printf("TK------>>>>>>Hello::Instance---------\n");
  if(_instance == 0){
    _instance = new Hello();
  }
  return _instance;
}

int Hello::setctl(int ctl)
{
  printf("TK------->>>>>>setctl-----\n");
  this->myctl = ctl;
  return 1;
}

int Hello::getctl(int ctl)
{
  printf("TK------->>>>>>getctl-----\n");
  return this->myctl;
}
编译成动态链接库,一般要求PIC位置无关:

g++ -shared -fPIC -o libhello.so hello.cpp

生成:libhello.so

2.测试用例

test.cpp

#include "so/hello.h"
#include <stdio.h>
#include <dlfcn.h>

int main()
{
  void* hello = dlopen("/home/lianxi/c++/ku/so/libhello.so", RTLD_LAZY);
  if(!hello){
    printf("dlopen /home/lianxi/c++/ku/so/libhello.so error!\n");
    return -1;
  }
  dlerror();
  CreatHelloClass* Creat_Hello = (CreatHelloClass*)dlsym(hello,"CreatHello");
  const char* dlsym_error = dlerror();
  if (dlsym_error) {
    printf("error %s\n",dlsym_error);
    return -1;
  }
  Hello_Base* mHello = Creat_Hello();
  mHello->setctl(5);
  int result = mHello->getctl(0);
  printf("TK------>>>>>result is %d\n",result);
  dlclose(hello);
  return 1;
}
编译:g++ -o test test.cpp -L. -ldl

执行./test结果:

TK------>>>>>>Hello::Instance---------
TK------->>>>>>setctl-----
TK------->>>>>>getctl-----
TK------>>>>>result is 5
二、分析

1.libdl库为C语言开发,当需要在C++中dlsym某个符号时、需要声明库中该符号为extern “C”,比如例子中的extern "C" Hello_Base* CreatHello();

2.由于不可能像C语言那样将C++类中的那么多方法都dlsym出来,这里使用了C++中对于纯虚类的实例化是运行时链接的特点;也就是说要在C++中对于类使用共享库的动态链接、必须定义一个纯虚的子类。

关于C中的共享库相关,请看如下链接:

《C编译原理》共享库的动态加载和静态加载


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值