簡體   English   中英

使用 extern "C" 時在 C++ 代碼中重載函數

[英]Overloading of functions in C++ code when using extern "C"

我想在運行時加載庫。 我有一個基類“Base”和兩個派生類“Derived1”和“Derived2”,它們應該在運行時加載。 我正在使用這個答案中的方法進行一些小的修改。 當我只定義一個派生類時,代碼編譯完美,但當定義多個派生類時,它無法編譯。 編譯錯誤如下:

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;
}

問題不在於extern "C" 問題是你有同一個函數的多個定義。

Base * create()是無法區分Base * create()

您要做的是在兩個不同的可加載模塊中具有相同的功能。 但是你正在做的是將這個函數的兩個實現(具有相同的名稱和簽名!)放入主模塊中,這當然會導致多個定義錯誤。

您應該做的是將create函數放入*.cpp文件中,即derived1.cppderived2.cpp ,從*.hpp文件中省略它們的定義,並從這些*.cpp文件中編譯共享對象。 我已經修改了您的項目以實現此目的,請參閱現場演示

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM