Linux下C++编程使用动态链接库
在《Linux下C编程使用动态链接库》一文中已了解到了C语言里如何使用共享库SO了,但在C++里可全是类,该如何实现呢?C语言中的操作只能导出全局函数,并不能导出类的方法,故而需要设计相关的全局函数来封装一层。这里用到了“类工厂函数”的设计模式,定义一个抽象类(含有纯虚函数)的头文件,然后在SO源文件和使用的源文件里均包含该头文件,在SO里继承并实现抽象类里的纯虚函数。
具体看下面的实例,头文件里创建多边形类(作为接口),而在SO继承它并实现三角形类,并且设计了全局的创建和销毁类对象的函数:polygon.hpp(纯虚父类,多边形类):
具体看下面的实例,头文件里创建多边形类(作为接口),而在SO继承它并实现三角形类,并且设计了全局的创建和销毁类对象的函数:polygon.hpp(纯虚父类,多边形类):
#ifndef POLYGON_HPP #define POLYGON_HPP class polygon { protected: double _side_length; public: polygon() : _side_length(0) {} virtual ~polygon() {} void set_side_length(double side_length) { _side_length = side_length; } virtual double area() const = 0; }; typedef polygon* create_t(); typedef void destroy_t(polygon*); #endif
triangle.cpp(三角形类,继承多边形类,实现其纯虚函数):
#include "polygon.hpp" #include <math.h> class triangle : public polygon { public: virtual double area() const { return _side_length * _side_length * sqrt(3) / 2; } }; extern "C" polygon* create() { return new triangle; } extern "C" void destroy(polygon* p) { delete p; }
cppso_exam.cpp:
#include "polygon.hpp" #include <iostream> #include <dlfcn.h> using namespace std; int main() { void * triangle_handle = dlopen("./triangle.so", RTLD_LAZY); if (!triangle_handle) { cerr << "dlopen failed: " << dlerror() << '\n'; return -1; } create_t * create_triangle = (create_t *)dlsym(triangle_handle, "create"); const char * dlsym_error = dlerror(); if (dlsym_error) { cerr << "Cannot load symbol 'create' : " << dlsym_error << '\n'; return -1; } destroy_t * destroy_triangle = (destroy_t *)dlsym(triangle_handle, "destroy"); dlsym_error = dlerror(); if (dlsym_error) { cerr << "Cannot load symbol 'destroy' : " << dlsym_error << '\n'; return -1; } polygon * poly = create_triangle(); poly->set_side_length(8); cout << "The area is : " << poly->area() << '\n'; destroy_triangle(poly); dlclose(triangle_handle); return 0; }
Makefile:
all: g++ -o triangle.so -shared -fPIC triangle.cpp g++ -rdynamic -o cppso cppso_exam.cpp -ldl clean: rm -rf triangle.so cppso
相应的源码文件目录树如下:
/home/xinu/xinu/c_cpp/cpp_so_example/ ├── cppso_exam.cpp ├── Makefile├── polygon.hpp └── triangle.cpp 我们在实现SO的triangle.cpp文件里看到了extern “C”,主要是为了处理Name Mangling的问题,即在C语言里函数名对应的符号名仍是函数名,而在C++里要支持函数重载,函数名对应的符号名则是函数名再加上参数名等组成,加上extern “C”是避免C++代码里找不到C函数(名字被改了),后期再详细说明该问题。
至此,我们了解了在类中进行共享库的处理方法。 参考网址:http://blog.sina.com.cn/s/blog_5eb8ebcb0101kn6w.htmlhttp://www.cppblog.com/pansunyou/archive/2010/11/09/linux_export_class.html
/home/xinu/xinu/c_cpp/cpp_so_example/ ├── cppso_exam.cpp ├── Makefile├── polygon.hpp └── triangle.cpp 我们在实现SO的triangle.cpp文件里看到了extern “C”,主要是为了处理Name Mangling的问题,即在C语言里函数名对应的符号名仍是函数名,而在C++里要支持函数重载,函数名对应的符号名则是函数名再加上参数名等组成,加上extern “C”是避免C++代码里找不到C函数(名字被改了),后期再详细说明该问题。
至此,我们了解了在类中进行共享库的处理方法。 参考网址:http://blog.sina.com.cn/s/blog_5eb8ebcb0101kn6w.htmlhttp://www.cppblog.com/pansunyou/archive/2010/11/09/linux_export_class.html
评论
发表评论