2012-04-11 3 views
2

Я пытаюсь создать шаблонный класс фабрики, который экспортирует создать метод:dllexport'ing статический метод шаблон

template <typename T> 
class ClassFactory 
{ 
    _declspec(dllexport) static void* Create() 
    { 
     return new T; 
    } 
}; 

class Foobar : ClassFactory<Foobar> 
{ 
    std::string foo; 
}; 

Этот код компилируется нормально, но я не вижу ничего в таблице экспорта когда это Я смотрю на выходе Dumpbin/экспорт

экспорт следующий код Create() правильно:

class ClassFactoryBase 
{ 
    _declspec(dllexport) virtual void* Create() = 0; 
}; 

template <typename T> 
class ClassFactory : ClassFactoryBase 
{ 
    void* Create() 
    { 
     return new T; 
    } 
}; 

class Foobar : ClassFactory<Foobar> 
{ 
    std::string foo; 
}; 

Однако, мне нужно создать(), чтобы быть статичным. Почему работает образец 2, а образец 1 - нет? Есть ли способ экспортировать статический шаблон?

+0

Ваш компилятор не поддерживает внешнюю связь для шаблонов. Мало кто делает, никто не поддержит его для модуля. Экспорт не может работать, вы должны переместить определения шаблонов в файл заголовка. –

ответ

0

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

+0

Я не ищу ClassFactory :: Create() для экспорта. Я хотел бы, чтобы ClassFactory :: Создать() для экспорта. Я понимаю, что этот метод должен быть скомпилирован как часть класса Foobar. Я что-то упускаю? – alexlesh

2

Компилятор видит, что функция Create() никогда не вызывается, поэтому она не генерирует никакого кода для нее. Чтобы сделать его работу, вам необходимо явно создать шаблон шаблона следующим образом:

template class ClassFactory<Foobar>; 

Просто добавьте эту строку в свой источник. Теперь компилятор будет генерировать код для этой функции и экспортировать его. Для получения дополнительной информации см. Статью MSDN. Explicit Instantiation (C++)

Чтобы ответить на ваш другой вопрос, почему пример 2 не работает, а пример 1 - нет, давайте более подробно рассмотрим производный класс Foobar. В этом классе есть виртуальная функция, поэтому компилятор должен сгенерировать таблицу vtable. Чтобы заполнить таблицу vtable, компилятор должен знать адрес Create(), и это когда он неявно создается из шаблона базового класса. Код для этой функции генерируется и экспортируется в DLL по запросу. Вот почему работает пример 2.

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