dllexport的静态模板方法

时间:2012-04-11 08:31:46

标签: c++ templates visual-c++ dll dllexport

我正在尝试创建一个导出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没有?有没有办法导出静态模板方法?

2 个答案:

答案 0 :(得分:2)

编译器发现永远不会调用Create()函数,因此它不会为它生成任何代码。要使其工作,您需要显式实例化您的模板,如下所示:

template class ClassFactory<Foobar>;

只需将此行添加到您的来源即可。现在编译器将为此函数生成代码并将其导出。有关详细信息,请参阅此MSDN文章 - Explicit Instantiation (C++)

为了回答你的另一个问题,为什么示例2有效,示例1没有,让我们仔细看看派生类Foobar。这个类中有一个虚函数,因此编译器必须生成一个vtable。要填写vtable,编译器需要知道Create()的地址,这是从基类模板隐式实例化的时候。生成此函数的代码并根据请求导出到DLL。这就是示例2有效的原因。

答案 1 :(得分:0)

无法从DLL导出模板方法,因为甚至没有编译非实例化模板方法。您的示例对DLL本身没有太大作用,头文件就是那个让一切正常工作的文件。