加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 钦州站长网 (https://www.0777zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

linux c++动态链接库so编写

发布时间:2022-10-12 11:06:13 所属栏目:Linux 来源:
导读:  Linux下的动态链接库是.so文件,即:Shared Object,下面是一个简单的例子说明如何写.so以及程序如何动态载入.so中的函数和对象。

  testso.h:

  #ifndef _TESTSO_H
  #define _TESTSO_H
  ex
  Linux下的动态链接库是.so文件,即:Shared Object,下面是一个简单的例子说明如何写.so以及程序如何动态载入.so中的函数和对象。
 
  testso.h:
 
  #ifndef _TESTSO_H
  #define _TESTSO_H
  extern "C" {
      int myadd(int a, int b);
      typedef int myadd_t(int, int); // myadd function type
  }
  #endif // _TESTSO_H
  testso.cpp:
 
  #include "testso.h"
  extern "C"
  int myadd(int a, int  b)
  {
      return a + b;
  }
  编译so:
 
  g++  -shared  -fPIC  -o testso.so testso.cpp
  注意,-shared参数和-fPIC参数非常重要:
 
  -shared 告诉gcc要生成的是动态链接库;
 
  -fPIC 告诉gcc生成的生成的代码是非位置依赖的,方面的用于动态链接。
 
  在主程序里调用这个动态链接库:
 
  main.cpp:
 
  #include
  #include
   // for dynamic library函数
  #include "testso.h"
  void print_usage(void)
  {
      printf("Usage: main SO_PATH/n");
  }
  int main(int argc, char *argv[])
  {
      if (2 != argc) {
          print_usage();
          exit(0);
      }
      const char *soname = argv[1];
      void *so_handle = dlopen(soname, RTLD_LAZY); // 载入.so文件
      if (!so_handle) {
          fprintf(stderr, "Error: load so `%s' failed./n", soname);
          exit(-1);
      }
      dlerror(); // 清空错误信息
      myadd_t *fn = (myadd_t*)dlsym(so_handle, "myadd"); // 载入函数
      char *err = dlerror();
      if (NULL != err) {
          fprintf(stderr, "%s/n", err);
          exit(-1);
      }
      printf("myadd 57 + 3 = %d/n", fn(57, 3)); // 调用函数
      dlclose(so_handle); // 关闭so句柄
      return 0;
  }
  编译主程序:
 
  g++ main.cpp -o main -ldl
 
  注意:要加上-ldl
 
  好了,上面就是如何写和调用动态库中的C函数。
 
  对于C++中的类,不能直接导出linux动态库,需要通过继承的方式才能从动态链接库中导出:
 
  =====================
 
  testso.h:
 
  #ifndef _TESTSO_H
  #define _TESTSO_H
  // 只能通过基类调用,因此需要先定义一个基类,然后在create中生成真正需要生成的对象。
  class Base
  {
  public:
      int a, b;
      virtual int add(void)
      {
          return -1;
      }
  };
  class A : public Base
  {
  public:
      int add(void);
  };
  extern "C" {
          Base* create(void);
          void destroy(Base *p);
          typedef Base* create_t(void);  // create factory
          typedef void destory_t(Base*); // destory
  }
  #endif // _TESTSO_H
  testso.cpp:
 
  #include "testso.h"
  int A::add(void)
  {
      return a + b;
  }
  extern "C"
  {
      Base* create(void) // 注意:create函数必须返回Base的对象,不能直接返回A的
                         //      对象,否则后面调用A::add()的时候会提示错误。
      {
          return new A;
      }
      void destory(Base *p)
      {
          if (p) delete p;
      }
  }
  main.cpp: // 这里需要注意
 
  #include
  #include
  #include
  #include "testso.h"
  void print_usage(void)
  {
      printf("Usage: myso SO_PATH/n");
  }
  int main(int argc, char *argv[])
  {
      if (2 != argc) {
          print_usage();
          exit(0);
      }
      const char *soname = argv[1];
      void *so_handle = dlopen(soname, RTLD_LAZY);
      if (!so_handle) {
          fprintf(stderr, "Error: load so `%s' failed./n", soname);
          exit(-1);
      }
      dlerror();
      create_t *create = (create_t*) dlsym(so_handle, "create");
      if (NULL != err) {
          fprintf(stderr, "%s/n", err);
          exit(-1);
      }
      Base *pa = create();
      pa->a = 57;
      pa->b = 3;
      printf("A.add(57, 3)=%d/n", pa->add()); // 注意,这里通过虚函数实现了
                                              // 对A::add()的调用。
      destory_t *destory = (destory_t*) dlsym(so_handle, "destory");
      if (NULL != err) {
          fprintf(stderr, "%s/n", err);
          exit(-1);
      }
      destory(pa);
      pa = NULL;
      dlclose(so_handle);
      printf("DONE!/n");
      return 0;
  }
 

(编辑:PHP编程网 - 钦州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!