美文网首页
Linux下C++编程使用动态链接库

Linux下C++编程使用动态链接库

作者: 网路元素 | 来源:发表于2019-10-29 00:10 被阅读0次

    在《Linux下C编程使用动态链接库》一文中已了解到了C语言里如何使用共享库SO了,但在C++里可全是类,该如何实现呢?C语言中的操作只能导出全局函数,并不能导出类的方法,故而需要设计相关的全局函数来封装一层。这里用到了“类工厂函数”的设计模式,定义一个抽象类(含有纯虚函数)的头文件,然后在SO源文件和使用的源文件里均包含该头文件,在SO里继承并实现抽象类里的纯虚函数。具体看下面的实例,头文件里创建多边形类(作为接口),而在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.html
    http://www.cppblog.com/pansunyou/archive/2010/11/09/linux_export_class.html

    相关文章

      网友评论

          本文标题:Linux下C++编程使用动态链接库

          本文链接:https://www.haomeiwen.com/subject/ogfryctx.html