Шаблон статических классов через динамические связанные библиотеки -- c++ поле с участием class поле с участием templates поле с участием static пол Связанный проблема

template static classes across dynamic linked libraries


1
vote

проблема

русский

У меня есть классовый класс со статическим значением, как это:

 <код>   template <class TYPE>  class A{   static TYPE value;  };   

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

 <код> 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

Английский оригинал

I have a templated class with a static value, like this:

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

in the code of a dll I assign the static value:

code of  DLL_1  A<float>::value = 2.0; 

I wish the value to be shared by all the dlls I'm using, i.e. I want that:

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

print out "2.0"

any clues? thx

</div
           

Список ответов

0
 
vote

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

 

I assume you're talking about Windows specifically, you you mention "DLL". As long as you mark you template class/struct as exported, you should be able to set the values in the DLL and use them in another DLL or program. As far as I understand it, on Windows this requires using __declspec(dllexport) when compiling the DLL that sets the values, and __declspec(dllimport) when compiling DLLs or programs that use the DLL. For example:
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; 

(The __declspec part is Windows specific. When using GCC on ELF systems (Linux and the like), you'd use __attribute__((__visibility__("default"))) to export a the class/struct, and nothing to import it. http://gcc.gnu.org/wiki/Visibility has some template code where you can set this up more easily.

</div
 
 
   
   
0
 
vote

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

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();   
 

You can manually manage instances of your static objects and find and solve duplicates by this way:

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); } 

How to use:

... // 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; ... 

Note: Anyway you need to make dllexport and any other actions to export and import for functions:

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

Связанный проблема

0  Как настроить VS2008 для эффективного развития C ++  ( How to setup vs2008 for efficient c development ) 
Обычно I Программируйте в C #, но были вынуждены выполнять работу в C ++. Похоже, что интеграция с Visual Studio (2008) действительно плохо по сравнению с C #...

501  Как использовать постоянную PI в C ++  ( How to use the pi constant in c ) 
Я хочу использовать постоянные и тригонометрические функции PI в некоторой программе C ++. Я получаю тригонометрические функции с помощью <код> include <math....

-1  Неожиданный идентификатор ошибки - не уверен, почему (C ++)  ( Unexpected error id not sure why c ) 
IM Реализация программы C ++, по соображениям проекта оно должно быть включено в один файл, поэтому я не могу поставить то, что вы обычно в отдельном файле за...

0  Libusb_Bulk_Transfer добавляет CRC?  ( Does libusb bulk transfer add crc ) 
Я пишу программу пользовательского интерфейса для устройства USB в C ++, используя Visual Studio 2019. Я использую библиотеку Libusb. Я хочу сделать объемную ...

0  Ошибка: аргумент типа "void (opca_hello ::) ()" не соответствует "void * (*) (void *)"  ( Error argument of type void opca hello does not match void void ) 
Я написал очень простой код для резьбы. Поскольку я очень новый для этого, я понятия не имею об ошибке. <код> class opca_hello { public: void hello(); } v...

2  Новый DataType, который может иметь количество до 100 цифр  ( New datatype which can have numbers upto 100 digits ) 
Примечание. Это был вопрос интервью и может не иметь фактического случая использования в настоящее время Вопрос должен был разработать класс, который может ...

-1  Бросить исключение, когда неправильный тип введен в  ( Throw exception when a wrong type is keyed in ) 
Я должен написать программу C ++, в которой функция состоит в том, чтобы прочитать два номера double Тип чисел из клавиатуры и добавить <код> try BLOCK, чт...

1  Почему 64-битное целое расширение C ++ называется «долгим долгом»?  ( Why is the 64bit integer extension of c called long long ) 
В отличие от других типов: «int», "логический", "двойной" и т. Д. И даже таможенные классы, есть только одно слово. Однако только одно слово для их типа тольк...

1  Не можете получить программу Math C ++ для работы [дубликата]  ( Cant get math c program to work ) 
<в сторону CLASS = "S-NEWACTS S-WELTIVE__info JS-Post-New Imide MB16« Роль = «Статус»> Этот вопрос уже есть ответы здесь : ...

0  Как получить несколько наборов результатов с Poco :: Data?  ( How to fetch multiple result sets with pocodata ) 
Я прочитал Poco :: Руководство пользователя данных и упоминается, что Библиотека имеет поддержку нескольких наборов результатов. Существует пример для этой ...

0  Проблема дизайна - создание шрифта Global (C ++, Marmalade)  ( Design issue making a font global c marmalade ) 
У меня есть проект Marmalade C ++, где встроенный в шрифте не масштабируется на экран. Чтобы справиться с этим вопросом, я делаю пользовательский шрифт, котор...

0  Правильный способ использования вариационного шаблона функции вызова со строковыми аргументами C ++  ( Proper way of using variadic template function call with string arguments c ) 
Здравствуйте, что не то, что я здесь делаю, используя вариадические шаблоны через строку? Как правильно использовать его для достижения заданий ниже? <код> ...

0  Использование аргументов Makefile без Foo =  ( Using makefile arguments without foo ) 
У меня есть makefile, который я использую для компиляции одного файла. Когда мне нужно пройти аргумент, я использую цель = TargetFile. Сценарий принимает ар...

5  Что такое "для (x: y)"?  ( What is for x y ) 
Итак, я оглянулся на межпубки о нитках, и я пришел в блог / учебную вещь о нитках, но то, что меня смущено, была эта линия, которую он использовал <код> for...

57  Как сделать макрос C ++ вести себя как функция?  ( How do i make a c macro behave like a function ) 
Допустим, по какой-то причине вам нужно написать макрос: <код> MACRO(X,Y) . (давайте предположим, что есть веская причина, по которой вы не можете использова...

Связанный проблема

0  Как настроить VS2008 для эффективного развития C ++ 
501  Как использовать постоянную PI в C ++ 
-1  Неожиданный идентификатор ошибки - не уверен, почему (C ++) 
0  Libusb_Bulk_Transfer добавляет CRC? 
0  Ошибка: аргумент типа "void (opca_hello ::) ()" не соответствует "void * (*) (void *)" 
2  Новый DataType, который может иметь количество до 100 цифр 
-1  Бросить исключение, когда неправильный тип введен в 
1  Почему 64-битное целое расширение C ++ называется «долгим долгом»? 
1  Не можете получить программу Math C ++ для работы [дубликата] 
0  Как получить несколько наборов результатов с Poco :: Data? 
0  Проблема дизайна - создание шрифта Global (C ++, Marmalade) 
0  Правильный способ использования вариационного шаблона функции вызова со строковыми аргументами C ++ 
0  Использование аргументов Makefile без Foo = 
5  Что такое "для (x: y)"? 
57  Как сделать макрос C ++ вести себя как функция? 



© 2021 www.qaru.top All Rights Reserved. Q&A House все права защищены


Licensed under cc by-sa 3.0 with attribution required.