我有一个带有静态值的模板化类,如下所示:
template <class TYPE>
class A{
static TYPE value;
};
在dll的代码中我分配静态值:
code of DLL_1
A<float>::value = 2.0;
我希望我正在使用的所有dll共享该值,即我想要:
code of DLL_2
printf("value on DLL_2 %f",A<float>::value);
打印出“2.0”
任何线索? THX
答案 0 :(得分: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系统(Linux等)上使用GCC时,您将使用__attribute__((__visibility__("default")))
导出类/结构,而无需导入它。http://gcc.gnu.org/wiki/Visibility有一些模板代码,您可以更轻松地设置它。
答案 1 :(得分: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();