шаблоны статических классов в динамически связанных библиотеках - PullRequest
1 голос
/ 18 июня 2010

У меня есть шаблонный класс со статическим значением, например:

  template <class TYPE>
 class A{
  static TYPE value;
 };

в коде dll присваиваю статическое значение:

code of  DLL_1

A<float>::value = 2.0;

Я хочу, чтобы значение было общим для всех используемых мной библиотек, т. Е. Я хочу, чтобы:

code of DLL_2

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

распечатать "2.0"

какие-нибудь подсказки? ТНХ

Ответы [ 2 ]

0 голосов
/ 26 марта 2014

Вы можете вручную управлять экземплярами ваших статических объектов и находить и устранять дубликаты следующим образом:

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();
0 голосов
/ 27 февраля 2011

Я предполагаю, что вы говорите именно о Windows, вы упоминаете "DLL".Пока вы помечаете свой шаблонный класс / структуру как экспортированные, вы должны иметь возможность устанавливать значения в DLL и использовать их в другой DLL или программе.Насколько я понимаю, в Windows это требует использования __declspec(dllexport) при компиляции DLL, которая устанавливает значения, и __declspec(dllimport) при компиляции DLL или программ, которые используют DLL.Например:
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. При использовании GCC в системах ELF (Linuxи т. д.), вы бы использовали __attribute__((__visibility__("default"))) для экспорта класса / структуры, и ничего для его импорта. http://gcc.gnu.org/wiki/Visibility имеет некоторый шаблонный код, где вы можете настроить его более просто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...