隐式使用静态库中的符号

时间:2018-03-26 07:10:14

标签: c++ design-patterns static-libraries

我在尝试隐式地从静态库导入符号时提交了一个问题。

让我用简单的代码来安排问题:

我有3个项目:      - 一个定义注册表类的静态插件处理程序项目,它在另外两个项目中链接      - 一个静态插件项目      - 一个具有插件处理程序和“静态加载”插件的最终项目。

首先,静态插件处理程序项目:

struct PluginType
{
    virtual void doMyStuff() = 0 ;
};

typedef PluginType* (*PluginCreator)();

struct Registry
{
      std::map<std::string, PluginCreator> _item_list;
      static Registry& instance()
      {
            static Registry singleton;
            return singleton;
      }
      static PluginType* create(std::string const& name)
      {
      // call the creator function that returns an PluginType*
        return instance()[name]();
      }
};

struct RecordInRegistry
{
     RecordInRegistry(std::string const& key, PluginCreator new_item_creator)
     {
          Registry::instance()._item_list[key] = new_item_creator;
     }
};

现在,一个静态插件项目

struct ADerivedItem : public PluginType
{
    virtual void doMyStuff() override
    {
        //some really interesting stuffs
    }
    static PluginType* create() { return new ADerivedItem() ; }
}


export "C" const RecordInRegistry i_record_derived_item_class("derived_item", &ADerivedItem::create);

然后,我使用插件的最终项目。这个项目链接了另外两个项目!

int main()
{
    PluginType*  my_instance = Registry::create("derived_item");

    return 0;
}

我希望通过链接静态库插件我能够注册我的静态插件 到项目。

它几乎奏效了!我得到的唯一问题是来自静态的符号“i_record_derived_item_class” 插件未在最终项目中显式使用,因此不会从静态插件lib中导入此符号!

我在visual studio上工作,我发现了一个简单的修复,包括强制符号导入,类似于 / INCLUDE:i_record_derived_item_class,一切正常。

我想知道你是否看到了解决这个问题的方法,我希望能够添加这种静态 通过链接来插入,而不必添加任何超过/LINK:myStaticPlugin.lib

有什么想法吗?

此外,避免使用特定于MSVC的解决方案真的很不错。

提前致谢!

1 个答案:

答案 0 :(得分:0)

问题是库中的符号仅在需要时使用。 n4659草案在5.2翻译阶段说[lex.phases]:

  
      
  1. 解析所有外部实体引用。库组件链接以满足外部引用   到当前翻译中未定义的实体
  2.   

由于您当前的源没有i_record_derived_item_class的外部引用,也没有类ADerivedItem的外部引用,默认情况下不会从插件项目中加载任何内容。更糟糕的是,即使插件处理程序模块也没有引用,因此您需要声明对构建系统本身的未定义引用,无论是MSVC还是其他任何内容。

或者,您可以将包含外部引用的最小翻译单元(表示.cpp或.o文件)链接到i_record_derived_item_class,以强制从库中进行解析。