我正在尝试创建一个导出create方法的模板化工厂类:
template <typename T>
class ClassFactory
{
_declspec(dllexport) static void* Create()
{
return new T;
}
};
class Foobar : ClassFactory<Foobar>
{
std::string foo;
};
这段代码编译得很好,但是当我查看 dumpbin / exports
的输出时,我在exports表中看不到任何内容以下代码正确导出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;
};
但是,我需要Create()为静态。为什么样本2有效,而样本1没有?有没有办法导出静态模板方法?
答案 0 :(得分:2)
编译器发现永远不会调用Create()
函数,因此它不会为它生成任何代码。要使其工作,您需要显式实例化您的模板,如下所示:
template class ClassFactory<Foobar>;
只需将此行添加到您的来源即可。现在编译器将为此函数生成代码并将其导出。有关详细信息,请参阅此MSDN文章 - Explicit Instantiation (C++)
为了回答你的另一个问题,为什么示例2有效,示例1没有,让我们仔细看看派生类Foobar。这个类中有一个虚函数,因此编译器必须生成一个vtable。要填写vtable,编译器需要知道Create()的地址,这是从基类模板隐式实例化的时候。生成此函数的代码并根据请求导出到DLL。这就是示例2有效的原因。
答案 1 :(得分:0)
无法从DLL导出模板方法,因为甚至没有编译非实例化模板方法。您的示例对DLL本身没有太大作用,头文件就是那个让一切正常工作的文件。