Объекты, не зарегистрированные на фабрике, когда код скомпилирован как библиотека, но отлично работает как отдельный - PullRequest
0 голосов
/ 18 января 2019

Мы пытаемся преобразовать наш код в библиотеку, чтобы обеспечить некоторый интерфейс с другими кодами. В коде мы часто используем фабрику объектов, основанную на одноэлементном шаблоне, в котором объекты объявляются с помощью макросов, реализованных в следующем порядке.

Наша проблема в том, что когда мы компилируем весь код в виде библиотеки, объекты больше не регистрируются на фабрике и не могут быть созданы при выполнении. Есть ли у вас какие-либо предложения? Примечательно, что что-то должно быть сделано внешним? Должен признаться, я достиг своих пределов ...

Большое спасибо!

Марк

template<typename AClass> class Factory
{
public :

    //! typedef for function creating object by the Factory
    typedef AClass*(*CreateFunc)();

    bool Register(const std::string& id,
          CreateFunc creator)
    {
        return _associations.insert(typename AssocMap::value_type(id, creator)).second;
    }

    bool Unregister(const std::string& id)
    { return _associations.erase(id) == 1; }

    AClass* CreateObject(const std::string& id)
    {

        typename AssocMap::const_iterator i=_associations.find(id);
        if(i!= _associations.end())
            return (i->second)();
        else
            {
                std::cerr << "Unknown Type in object factory : " << id << std::endl;
                exit(-1);
            }
    }

    AClass* CreateObjectIfAvailable(const std::string& id)
    {

        typename AssocMap::const_iterator i=_associations.find(id);
        return (i!= _associations.end() ? (i->second)() : NULL);

    }

    static Factory & Instance()
    {
        static Factory obj;
        return obj;
    }

private:

    //! AssocMap typedef used for map establishing correspondance between CL and std::strings
    typedef std::map<std::string,CreateFunc> AssocMap;

    // Singleton implies creation/destruction entirely private
    Factory():_associations(std::map<std::string,CreateFunc>()) {}

    //! Factory declared private to avoid bad surprises
    Factory(const Factory&);

    //!operator= declared private to avoid bad surprises
    Factory& operator=(const Factory&);

    ~Factory() {}

    //! associations_ contains the correspondance between std::strings and objects
    AssocMap _associations;

};

#define DECLARE_CONSTITUTIVE_LAW(CLASS_NAME,KEYWORD)                    \
    namespace {                             \
    AbstractConstitutiveLaws* creator(){ return new (CLASS_NAME);}  \
    const std::string kwords(KEYWORD);              \
    const bool registered = Factory<AbstractConstitutiveLaws>::Instance().Register(kwords,creator); \
    }
...