如何导出类模板静态变量 DLL windows

Posted

技术标签:

【中文标题】如何导出类模板静态变量 DLL windows【英文标题】:How to export a class template static variable DLL windows 【发布时间】:2015-10-12 10:55:20 【问题描述】:

我不知道如何将模板内的静态变量导出到我的可执行文件。

我正在使用具有组件模板的 entityx 库:

实体.h:

struct BaseComponent 
public:
  typedef size_t Family;
protected:
  static Family family_counter_; //THIS!!
;

template <typename Derived>
struct Component : public BaseComponent 
 public:
  typedef ComponentHandle<Derived> Handle;
  typedef ComponentHandle<const Derived, const EntityManager> ConstHandle;

private:
  friend class EntityManager;
  /// Used internally for registration.
  static Family family();
;

Entity.cpp:

BaseComponent::Family BaseComponent::family_counter_ = 0;

现在我的库链接到 entityx 并使用它: 世界.hpp:

#include <entityx/entityx.h>

namespace edv 
class Transform : public entityx::Component<Transform> 
public:
    Transform();
;

class World 
public:
    World();
    entityx::Entity createEntity();
private:
    entityx::EventManager m_events;
    entityx::EntityManager m_entities;
;

世界.cpp:

#include <Endavant/game/World.h>
#include <iostream>

namespace edv 
Transform::Transform() 


World::World(): m_entities(m_events)


void World::update() 


entityx::Entity World::createEntity() 
    auto e = m_entities.create();
    e.assign<Transform>();
    auto c = e.component<Transform>();
    if (c.valid()) 
        std::cout<<"createEntity componenthdnlr OK!!"<<e.id()<<std::endl;
     else 
        std::cout<<"createEntity componenthdnlr INVALID!!"<<e.id()<<std::endl;
    
    return e;



现在我构建了一个可执行的“myprogram.exe”,它链接到我的库 EDV 和 entityx:

#include <Endavant/Root.h>
#include <Endavant/game/World.h>

void test() 
    auto entity = edv::Root::get().getWorld().createEntity();
    auto comp = entity.component<edv::Transform>();

    if (comp.valid()) 
        std::cout<<"test componenthndlr VALID!!"<<entity.id()<<std::endl;
     else 
        std::cout<<"test componenthndlr INVALID!!"<<entity.id()<<std::endl;
    


int main() 

    try 
        edv::Root::get().init();
        test();
        edv::Root::get().run();
     catch (std::exception & e) 
        std::cout<<e.what()<<std::endl;
    
    return 0;

当我执行“myprogram.exe”时,它会输出:

createEntity componenthdnlr OK!!
test componenthndlr INVALID!!

我调试了应用程序,似乎有两个“family_counter_”静态变量实例,一个用于我的 dll,另一个用于可执行文件“myprogram.exe”。

当我在 Linux 中编译时,它按预期工作:

createEntity componenthdnlr OK!!
test componenthndlr OK!!

所以我认为这应该与 GCC 中的 Windows DLL 可见性有关。 我是这个 Windows DLL 世界的新手,我不知道我必须在哪里以及导出什么才能使其正常工作。

我正在使用 MSYS2 和 GCC 5.2.0 来编译它。 谢谢

【问题讨论】:

【参考方案1】:

我不知道这是否是最好的解决方案,但它确实有效:

extern template class entityx::Component&lt;edv::Transform&gt;;

这样它只会创建该静态变量的一个实例。

【讨论】:

以上是关于如何导出类模板静态变量 DLL windows的主要内容,如果未能解决你的问题,请参考以下文章

Windows中的库编程

DLL导出类静态成员函数问题

如何在c#中使用C++ dll导出类[重复]

dll从静态链接库导出函数符号

跨 dll 使用静态类变量/函数

如何要求消费者使用类库来初始化静态变量