2015-08-16 1 views
4

Я хочу использовать ключевое слово 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 внутри, можем ли мы быть уверенными, что это не будет проблемой в любом контексте?

Есть ли какие-либо вопросы, которые я не рассматривал в своем вопросе?

+0

Когда вы говорите «для статических переменного», вы на самом деле имели в виду * как * а статическая переменная? Если нет, то что? – EJP

+0

@EJP Я перефразировал его, лучше? Я понятия не имею, как это лучше сказать.Пожалуйста, сделайте предложение, если оно еще не понятно. – Ident

+1

Вы нашли решение проблемы по-прежнему? Я спрашиваю, потому что у меня такая же проблема ... – mattmilten

ответ

0

Когда dll загружается, он загружается с собственной моделью памяти. Следовательно, любой статический код не будет использоваться для разных процессов.

+0

Я не уверен, как это отвечает на мой вопрос. Я немного перефразировал эту тему, чтобы яснее понять, что я имею в виду. В любом случае, не могли бы вы подробнее рассказать о своем ответе? – Ident

Смежные вопросы