Я хочу использовать ключевое слово C++ 11 thread_local в нашей библиотеке Open Source, которая может быть динамически или статически связана на многих платформах (Windows, Linux, Mac OS, ...) в контексте статической переменной. Эта переменная имеет тип класса, который в основном просто инкапсулирует переменную std :: stringstream и инициализирует ее в соответствии с требованиями форматирования строк. Мы хотим, чтобы эта статически была доступна по соображениям производительности (см. Мои предыдущие question для более подробной информации), и это нормально, если это делается для каждого потока.Может ли thread_local использоваться для предоставления статической глобальной переменной в dll для каждого потока?
Глобальная переменная должна использоваться в статических шаблонных методах класса, которые должны быть реализованы в заголовке. Но это означает, если я правильно понимаю, что пользователь библиотеки может включать этот заголовок в свой код исполняемого файла, который бы скомпилировал шаблонные методы в исполняемый файл. Эти методы затем будут обращаться к указанной глобальной переменной из потока исполняемого файла. Как мне нужно объявить/определить статическую переменную, чтобы это работало, то есть мне нужно экспортировать переменную или тип класса или достаточно, чтобы объявить ее «static thread_local X»? Это мое нынешнее заявление:
// SharedStringstream.h
#include <sstream>
// Export stands for _declspec(dllimport) or (dllexport) respectively
class EXPORT SharedStringstream
{
public:
SharedStringstream();
static thread_local SharedStringstream s_sharedStreamInstance;
std::stringstream d_sharedStream;
};
и определение:
// SharedStringstream.cpp
#include "SharedStringStream.h"
SharedStringstream SharedStringstream::s_sharedStreamInstance();
SharedStringstream::SharedStringstream()
{
d_sharedStream.imbue(std::locale("C"));
d_sharedStream << std::skipws;
d_sharedStream >> std::skipws;
}
Без экспорта я получаю ошибки компоновщика, с ним я получаю следующее сообщение об ошибке в Visual Studio 2015:
Ошибка C2492 'public: static SharedStringstream SharedStringstream :: s_sharedStreamInstance': данные с продолжительностью хранения потоков могут не иметь интерфейса dll
Дополнительная информация дана , которая в основном утверждает, что переменная thread_local
не может быть экспортирована. Мне нужно было бы переместить его из класса в мое пространство имен для этой цели, это единственный способ?
Далее: На странице MSDN на "Thread Local Storage" говорит следующее в отношении thread_local
и библиотек DLL:
Использование атрибута нити может помешать задержки загрузки DLL импорта.
Мы используем задержку загрузки DLL для некоторых плагинов, из которых состоит наша библиотека, но вызовы этой переменной не будут. Я предполагаю, что пользователи могут, однако, задерживать загрузку библиотеки, хотя мы официально ее не поддерживаем. Предполагая, что мы не поддерживаем задержку загрузки нашей библиотеки и не вызываем переменную из любых загруженных с задержкой DLL внутри, можем ли мы быть уверенными, что это не будет проблемой в любом контексте?
Есть ли какие-либо вопросы, которые я не рассматривал в своем вопросе?
Когда вы говорите «для статических переменного», вы на самом деле имели в виду * как * а статическая переменная? Если нет, то что? – EJP
@EJP Я перефразировал его, лучше? Я понятия не имею, как это лучше сказать.Пожалуйста, сделайте предложение, если оно еще не понятно. – Ident
Вы нашли решение проблемы по-прежнему? Я спрашиваю, потому что у меня такая же проблема ... – mattmilten