相关疑难解决方法(0)

共享库中的类和静态变量

我正在尝试使用以下架构在c ++中编写内容:

App - > Core(.so)< - 插件(.so)

对于linux,mac和windows.Core隐式链接到App,而插件显式链接到dlopen/LoadLibrary到App.我遇到的问题:

  • Core中的静态变量在运行时被复制 - 插件和应用程序具有不同的副本.
  • 至少在mac上,当Plugin返回指向App的指针时,动态转换App中的指针总是导致NULL.

    有人可以给我一些不同平台的解释和说明吗?我知道在这里问他们所有人似乎都很懒,但我真的找不到这个问题的系统答案.

    我在entry_point.cpp中为插件做了什么:

    #include "raw_space.hpp"
    
    #include <gamustard/gamustard.hpp>
    
    using namespace Gamustard;
    using namespace std;
    
    namespace
    {
      struct GAMUSTARD_PUBLIC_API RawSpacePlugin : public Plugin
      {
        RawSpacePlugin(void):identifier_("com.gamustard.engine.space.RawSpacePlugin")
        {
        }
    
        virtual string const& getIdentifier(void) const
        {
          return identifier_;
        }
    
        virtual SmartPtr<Object> createObject(std::string const& name) const
        {
          if(name == "RawSpace")
          {
            Object* obj = NEW_EX RawSpaceImp::RawSpace;
            Space* space = dynamic_cast<Space*>(obj);
            Log::instance().log(Log::LOG_DEBUG, "createObject: %x -> %x.", obj, space);
            return SmartPtr<Object>(obj);
          }
          return SmartPtr<Object>();
        }
    
      private: …
    Run Code Online (Sandbox Code Playgroud)
  • c++ shared-libraries

    28
    推荐指数
    1
    解决办法
    2万
    查看次数

    如何使用extern模板

    我一直在查看C++ 0x的N3291工作草案.我对extern模板感到好奇.第14.7.3节规定:

    除了内联函数和类模板特化之外,显式实例化声明具有抑制它们引用的实体的隐式实例化的效果.

    仅供参考:"明确的实例化声明"一词是标准的extern template.这已在第14.7.2节中定义.

    这听起来像是在说如果你使用extern template std::vector<int>,那么做任何通常隐式实例化的事情std::vector<int>都不会这样做.

    下一段更有趣:

    如果实体是同一翻译单元中的显式实例化声明和显式实例化定义的主题,则该定义应遵循声明.作为显式实例化声明的主体并且以在否则将导致翻译单元中的隐式实例化(14.7.1)的方式中使用的实体应该是程序中某处的显式实例化定义的主题; 否则该程序格式错误,无需诊断.

    仅供参考:术语"显式实例化定义"是这些事物的标准说法:template std::vector<int>.也就是说,没有了extern.

    对我来说,这两件事说extern template防止了隐式实例化,但它并没有阻止显式实例化.所以,如果你这样做:

    extern template std::vector<int>;
    template std::vector<int>;
    
    Run Code Online (Sandbox Code Playgroud)

    第二行有效地否定了第一行,明确地做了第​​一行隐含发生的事情.

    问题是:Visual Studio 2008似乎不同意.我想要使​​用的方法extern template是阻止用户隐式实例化某些常用模板,以便我可以在.cpp文件中显式实例化它们以减少编译时间.模板只会实例化一次.

    问题是我必须在VS2008中围绕它们#ifdef.因为如果单个翻译单元看到extern和非extern版本,它将使extern版本获胜并且没有人会实例化它.然后是链接器错误.

    所以,我的问题是:

    1. 根据C++ 0x,正确的行为是什么?应该extern template防止明确的实例化吗?
    2. 如果上一个问题的答案是它不应该,那么VS2008是错误的(被授予,它在规范之前写得很好,所以它不像是他们的错).VS2010如何处理这个问题?它是否实现了正确的extern template行为?

    c++ templates visual-studio-2008 explicit-instantiation c++11

    24
    推荐指数
    1
    解决办法
    1万
    查看次数

    不同dll中的C++模板特化会产生链接器错误

    我有一个第三方dll包含一个具有多个特化的模板类.我在Linux上有自己的专业,试图编译一个Windows DLL然而导致链接器错误.

    我试了一下,发现模板头上的dllimport规范可能是原因,删除它会解决我的问题.但是我不想修改或复制标题,因为它可能会随着第三方库的每次更新而中断.

    这是一个重现我的问题的最小例子

    test.h - dll/so header:

    #ifdef _WIN32
    #ifdef EXPORT
    #    define LIB_EXPORT __declspec(dllexport)
    #else
    #    define LIB_EXPORT __declspec(dllimport)
    #endif
    #else
    #    define LIB_EXPORT
    #endif
    
    template <typename A> class LIB_EXPORT Foobar
    {
       public:
          virtual void helloWorld(){}
          virtual ~Foobar(){}
    }; 
    
    Run Code Online (Sandbox Code Playgroud)

    test.cpp - dll/so impl:

    #define EXPORT
    #include "test.h" 
    
    template class __declspec(dllexport) Foobar<int>;
    
    Run Code Online (Sandbox Code Playgroud)

    main.cpp - 示例程序:

    #include "test.h"
    //explicit instanciation - does not help
    template class __declspec(dllexport) Foobar<char>;
    int main(int argc, char** argv)
    {
        Foobar<char> a;
        a.helloWorld();
    }
    
    Run Code Online (Sandbox Code Playgroud)

    有没有一种干净的方法可以在我的可执行文件中完整地实例化Foobar?

    使用的编译器:Visual …

    c++ dll templates dllimport visual-studio-2010

    1
    推荐指数
    1
    解决办法
    2334
    查看次数