Статическая членская переменная в шаблоне, с несколькими dlls

Вам нужно использовать отражение, чтобы начать использовать метод, а затем «построить» его, предоставив аргументы типа MakeGenericMethod :

MethodInfo method = typeof(Sample).GetMethod("GenericMethod");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(this, null);

. Для статического метода, pass null в качестве первого аргумента Invoke. Это не имеет никакого отношения к универсальным методам - ​​это просто нормальное отражение.

Как уже отмечалось, многое из этого проще с C # 4 с использованием dynamic - если вы можете использовать вывод типа, конечно. Это не помогает в случаях, когда вывод типа недоступен, например, точный пример в вопросе.

18
задан Igor Oks 29 December 2008 в 17:42
поделиться

7 ответов

Создайте шаблонную специализацию и затем экспортируйте статических членов специализации.

2
ответ дан 30 November 2019 в 09:28
поделиться

Проблема состоит в том, что каждое различное шаблонное инстанцирование является другим типом со своей собственной статической переменной, которая не совместно используется с другими экземплярами, которые имеют различные шаблонные параметры. Вы могли обеспечить нешаблонный базовый класс, который содержит статическую переменную.

2
ответ дан 30 November 2019 в 09:28
поделиться

Вы уже пробуете это использование:

#pragma data_seg(".JOE")
HWND hWndServer = NULL;
HHOOK hook = NULL;
#pragma data_seg()
#pragma comment(linker, "/section:.JOE,rws")  

Примечание, которое переменная должна излучить инициализированный.

[еще 115] информация: http://msdn.microsoft.com/en-us/library/ms997537.aspx http://www.flounder.com/hooks.htm

Удача.

1
ответ дан 30 November 2019 в 09:28
поделиться

Существуют два, фиксирует для этой проблемы, которую я вижу.

Первый то, что Вы используете другой класс, тот, который не является шаблоном, чтобы содержать это статическое значение - или сделать его глобальным? - и экспорт это из dll.

другой немного гумус, сложный в этом, Вы инстанцируете шаблона в коде и экспорте, который инстанцировал шаблонного значения (значений). Таким образом для предоставления примера говорят, что у меня был специальный вид связанного списка, обработал класс по шаблону и должен был иметь статическое значение, совместно использованное через DLL. Я написал код, который будет шаблонным, но он только действительно используется для некоторого небольшого количества типов. Я инстанцировал бы классов как таковых:

template <class T> class Foo;
template<> class Foo<int> {};

Затем Вы могли экспортировать статические переменные, содержимые в.

__declspec(dllexport) int Foo<int>::StaticMember = 0;

(Или что-то как этот, я немного ржав с выполнением dll экспорт/импорт.)

, Хотя реальный вопрос состоит в том, почему Вы хотели бы сделать это, как технически, DLL может использоваться через процессы только с одной копией, сохраненной в памяти. Вы действительно хотите там только быть одной версией помех для всех процессов или одной для каждого процесса?

1
ответ дан 30 November 2019 в 09:28
поделиться

До extern template инстанцирования, принимаемые в черновой стандарт, кажется, что Microsoft реализовала расширение для VC ++ компилятор.

VC ++ компилятор генерирует предупреждение, если нестандартное расширение будет использоваться; VS.NET (2003) и выше относится к этому предупреждение описание для деталей. Это предупреждение также перечислено против VS 6.0.

я лично никогда не пытался использовать это расширение, таким образом, я не могу ручаться за это предложение. Очевидно, я ограничиваю этот ответ на Microsoft Visual Studio (я видел комментарий от Вас относительно Unix), но я отправляю в надежде, что это может оказаться полезным.

0
ответ дан 30 November 2019 в 09:28
поделиться

Также существует следующее решение:

  • в библиотеке : явно создать экземпляр некоторой специализации шаблона и поделиться им с dllexport
  • в основной программе :
    • если специализация доступна, она будет использоваться из библиотеки
    • , если специализация недоступна, она скомпилирована в основной программе

Подробное описание того, как это сделать:

Блог Антеру Явно создание шаблона

4
ответ дан 30 November 2019 в 09:28
поделиться

Похоже, есть способ сделать это с меньшими ограничениями для кода, использующего шаблонный класс.

Сделайте статический член указателем. Создайте глобальную карту с фиксированным известным типом, которую можно экспортировать из DLL. Карта использует typeid () класса в качестве ключа и адрес «глобальной переменной для класса» в качестве значения. Инициализируйте статический член с помощью функции, которая проверяет, существует ли класс уже на карте, и если да, то заставляет вторую версию класса (во второй DLL) указывать на статическую переменную первой версии класса.

Таким образом, каждая DLL имеет отдельный статический объект, но каждая DLL также имеет указатель, и все указатели указывают на один и тот же статический объект.

Вот некоторый псевдокод, предполагающий статический ' Тип s такой же, как параметр шаблона (но должен быть легко адаптирован для других случаев).

map<string,void*> dllexport the_map;  // instantiate this once in a single DLL

T *set_the_global(T *candidate) {
  map<string,void*>::iterator r = the_map.find(string(typeid(the_class<T>).name()));
  if(r == the_map.end()) {
    the_map[string(typeid(the_class<T>).name())] = (void*)candidate;
    return candidate;  // new class: use it as global storage location
  } else {
    return (T*)(r->second);  // class already has global storage location
  }
}

template <class T> class the_class {
  virtual void something();  // so RTTI exists
  static T *the_global;  // use this! always points to the same object
  static T one_per_dll;  // only used in initialisation
};
template<class T> the_class<T>::one_per_dll;
template<class T> the_class<T>::the_global = set_the_global(&the_class<T>::one_per_dll)
2
ответ дан 30 November 2019 в 09:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: