【问题标题】:Getting around issues with templates inside Dll in C++?在 C++ 中解决 Dll 中的模板问题?
【发布时间】:2017-04-09 11:10:33
【问题描述】:

背景:

我目前在 Visual Studio 中构建了一个游戏引擎项目,以便将我的“引擎”编译为 dll,供另一个项目“游戏”使用。我的想法是我可以换出不同的游戏项目并仍然使用相同的引擎 dll 代码。在我的引擎代码中,我正在创建自己的框架,所有其他引擎代码都将使用该框架。这将有助于将我的实现与我的其余代码分开,并在需要时使修改更容易。

由于我的所有框架代码都在 dll 本身中使用,而不是在“游戏”中使用,我认为我可以实现模板。但是,每当我尝试使用引擎框架实现模板时,我仍然会收到“未定义符号”错误。

问题:

有没有办法从我的 dll 中的链接器中绕过模板的“未定义符号”错误,而不必explicitly define 我的模板将使用的每种类型(例如class template MyClass<int>class template MyClass<float> 等) ?如果没有,对于我可以实现引擎和不同游戏项目以保持灵活性的不同方式有什么建议吗?感谢您的任何意见。

附:我不想显式定义模板类可以使用的所有类型,因为如果我想创建自己的向量模板类(因为我必须定义很多不同的类),那会变得相当大。

【问题讨论】:

  • 我相信显式导出模板的实例化是将所有代码都放在头文件中的解决方法。一种比这更简洁的方法(例如,SFML 使用的方法)是让模板头只包含声明,然后在底部 #include 类似于定义实现的 .inl 文件。然后它全部在包含文件中,但标题本身对用户来说是干净的。

标签: c++ templates dll game-engine undefined-symbol


【解决方案1】:

模板实例化在编译时生成,因此如果您不想单独声明所有可能的实例化,则必须将所有模板定义移动到头文件中。

这样做的一种常见方法是让每个类都将所有模板定义放在一个内联文件中,例如 .inl.cxx 文件,然后将该内联文件包含在相应头文件的末尾.

例如,对于具有单个模板化函数的类 Foo

Foo.hpp的内容:

class Foo
{
    template <typename T>
    void bar();
};

#include "Foo.inl" // Include template definitions

Foo.inl的内容:

template <typename T>
void Foo::bar()
{
    // body
}

这样,每当Foo::bar&lt;T&gt; 与新的T 一起使用时,就会生成一个新的模板实例化。

【讨论】:

    【解决方案2】:

    “我不想显式定义模板类可以使用的所有类型,因为那样会变得相当大”

    您希望 DLL 包含什么?它要么包含MyClass&lt;float&gt;,要么不包含。并且编译器会为它知道的每种类型实例化MyClass&lt;T&gt;,你的DLL 将是巨大的

    【讨论】:

      【解决方案3】:

      模板应该是内联代码。当编译器遇到模板的使用时,他们的代码在代码生成步骤创建,并带有该用例的代码。一般来说,试图强制编译器基于模板创建类是一种谬误,性能问题和不便,与拥有模板的目的相反。

      一般而言,如果您的专用变体数量有限,您需要声明专用模板的对象(变量)以强制编译器生成一个

      大多数模板库在头文件中完全声明方法代码,并且可能根本没有二进制对象文件。就像mock_blatt在评论中说的那样,在头文件中声明模板,并在头文件中使用的包含文件中的方法和朋友的实现。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-04
        • 2021-11-11
        • 1970-01-01
        • 2019-03-17
        • 1970-01-01
        • 2011-05-04
        • 2021-11-21
        相关资源
        最近更新 更多