微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用外部“ C”时C ++代码中的函数重载

如何解决使用外部“ C”时C ++代码中的函数重载

我想在运行时加载库。我有一个基类“ Base”和两个派生类“ Derived1”和“ Derived2”,应在运行时加载它们。我正在使用this answer中的方法进行一些小的修改。当我仅定义一个派生类时,代码可以完美地编译,但是当定义多个派生类时,代码将无法编译。编译错误如下:

multiple deFinitions of 'create'

我认为问题是“ C”不允许重载函数名称一个人将如何解决这个问题?

重要的一点是,由于我不知道存在多少.so文件,因此我想为所有.so文件使用一个处理程序。代码的详细信息如下:

base.hpp

class Base {
public:
    virtual ~Base() {}
    virtual void foo() const = 0;
};

using Base_creator_t = Base *(*)();

derived1.hpp

#include "Interface.hpp"

class Derived1: public Base {
public:
    void foo() const override {}
};

extern "C" {
Base * create() {
    return new Derived1;
}
}

derived2.hpp

#include "Interface.hpp"

class Derived2: public Base {
public:
    void foo() const override {}
};

extern "C" {
Base * create() {
    return new Derived2;
}
}

动态共享库处理程序:Derived_factory.hpp

#include <dlfcn.h>

class Derived_factory {
public:
    Derived_factory(char* path) {
        handler = dlopen(path,RTLD_Now);
        if (! handler) {
            throw std::runtime_error(dlerror());
        }
        Reset_dlerror();
        creator = reinterpret_cast<Base_creator_t>(dlsym(handler,"create"));
        Check_dlerror();
    }

    std::unique_ptr<Base> create() const {
        return std::unique_ptr<Base>(creator());
    }

    ~Derived_factory() {
        if (handler) {
            dlclose(handler);
        }
    }

private:
    void * handler = nullptr;
    Base_creator_t creator = nullptr;

    static void Reset_dlerror() {
        dlerror();
    }

    static void Check_dlerror() {
        const char * dlsym_error = dlerror();
        if (dlsym_error) {
            throw std::runtime_error(dlsym_error);
        }
    }
};

main.cpp

#include "Derived_factory.hpp"
int main(){
   Derived_factory factoryOne("Derived1.so");
      std::unique_ptr<Base> baSEOne = factoryOne.create();
      baSEOne->foo();
   Derived_factory factoryTwo("Derived2.so");
     std::unique_ptr<Base> baseTwo = factoryTwo.create();
     baseTwo->foo();
   return 0;
}

解决方法

问题不是ncpus=3。问题是您有同一个函数的多个定义。

extern "C"Base * create()

不能区别 ,

您想要做的是在两个不同的可加载模块中具有相同的功能。但是,您要做的是将该函数的两个实现(具有相同的名称和签名!)放入主模块,这当然会导致多个定义错误。

您应该做的是将create函数放入*.cpp文件中,即derived1.cppderived2.cpp,从*.hpp文件中省略它们的定义,然后从这些*.cpp文件中编译共享对象。我已经修改了您的项目以实现此目标,请参见live demo

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。