2010-06-18 63 views
1

我有一个模板类有一个静态值静态类,就像这样:模板横跨动态链接库

code of DLL_1 

A<float>::value = 2.0; 

我:

template <class TYPE> 
class A{ 
    static TYPE value; 
}; 
在DLL中我指定的静态值的代码

希望值由我使用的所有DLL共享,也就是我想要的是:

code of DLL_2 

printf("value on DLL_2 %f",A<float>::value); 

打印出“2.0”

任何线索? THX

+0

全局变量重新访问 – ereOn 2010-06-18 11:47:39

回答

0

我假设你特别谈到Windows,则您提到“DLL”。只要您将模板类/结构标记为导出,您应该能够设置DLL中的值并将它们用于另一个DLL或程序中。 据我了解,在Windows上,编译设置值的DLL时需要使用__declspec(dllexport),编译使用DLL的DLL或程序时需要使用__declspec(dllimport)。例如:
dll.h:

#ifdef BUILDING_MY_DLL 
# define MY_API __declspec(dllexport) 
#else 
# define MY_API __declspec(dllimport) 
#endif 
template<class TYPE> 
struct MY_API A { 
    static TYPE value; 
}; 

dll.cpp:

#include "dll.h" 
template<> 
A<float>::value = 2.0f; 

(该__declspec部分是Windows特定当ELF系统使用GCC(Linux和等),你” d使用__attribute__((__visibility__("default")))来导出类/结构体,而不需要导入它http://gcc.gnu.org/wiki/Visibility有一些模板代码,您可以更容易地设置它

+0

这是行不通的。专业化没有在头文件中声明,所以其他翻译单元将不知道它存在。换句话说,一个定义规则被违反。 – 2011-02-27 14:53:31

+0

它应该工作,因为符号将在DLL中发射,然后当引用正常的符号查找应该适用。我只在这里谈论静态类变量。 (我在Ubuntu上使用g ++进行测试,符号导出到库中,其他库或程序可以引用它们) – 2011-02-27 15:56:47

0

您可以手动管理静态对象的实例,通过这种方式解决重复:

myfile.h:

// Base class which will make linked list of all static instances 
class Base { 
protected: 
    // make linked list overall template instances 
    static Base *first, *last; 
    Base *prev, *next; 

    Base(); 
    virtual void set_alias(Base *alias) = 0; 
    virtual ~Base(); 
    static void initialize(); 
} 

// Your template class with template static members 
template<typename T> 
class MyClass: public Base { 
protected: 
    T own_data; 
    T *aliased_data; 

    virtual void set_alias(Base *alias) { 
     aliased_data = alias == NULL ? &own_data : ((MyClass<T>*)alias)->aliased_data; 
     //if (aliased_data != &own_data) { 
     // .... here you can merge data from two clones of template, if need 
     //} 
    } 

public: 
    // data accessors 
    inline T& data() { return *aliased_data; } 
    inline const T& data() const { return *aliased_data; } 

    // single instance of class by this you can access staic data field 
    static MyClass instance; 
} 

MYFILE.CPP:

#include <typeinfo> 
#include <string> 

Base *Base::first = NULL; 
Base *Base::last = NULL; 

// connect each created instance to static fields 
Base::Base(): prev(last), next(NULL) { 
    last = (first == NULL ? first : last->next) = this; 
} 

Base::~Base() { 
    (prev == NULL ? first : prev->next) = next; 
    (next == NULL ? last : next->prev) = prev; 
} 

// find all duplicates and connect it togather 
// compare instances by mangled typename 
// Note: Base should contain virtual methods so typeid will works proper 
Base::initialize() { 
    for(Base *i = first; i != NULL; i = i->next) 
     for(Base *j = i->next; j != NULL; j = j->next) 
       if (std::string(typeid(*i).name()) == typeid(*j).name()) 
        j->set_alias(*i); 
} 

如何使用:

... 
// call initialize when program started and DLL 
// with implementation of class Base was loaded 
Base::initialize(); 
... 

... 
// call initialize again when any other dll which uses MyClass loaded 
Base::initialize(); 
... 

... 
// now we can use MyClass from any function (from DLL and/or from main program) 
MyClass<float>::instance.data() = 10.f; 
... 

... 
std::cout << MyClass<float>::instance.data() << std::endl; 
... 

注:反正你需要做dllexport以及任何其他用于输出和输入功能的操作:

Base::Base(); 
virtual void Base::set_alias(Base *alias) = 0; 
virtual Base::~Base(); 
static void Base::initialize();