c++ - 如何保持内联调用但避免编译器警告?

标签 c++ visual-c++ dll

我有一个类,它被广泛用于我软件中的所有代码。此类是具有一些几何函数的点抽象,它由坐标类型模板化,例如 long 或 double。如果这个点在动态库之间传递,我会收到编译器警告 C4252: class 'Point' needs to have dll-interface to be used by clients of class 'OtherClass' 但代码运行良好且快速,因为所有库具有相同的编译设置。

由于我们的政策是完全没有警告,因此我们决定将两个广泛使用的模板特化标记为 dll 导出,如下所示(在带有模板的 header 中):

 template class __declspec(dllexport) Point<long>;
 template class __declspec(dllexport) Point<double>;

但是现在编译器用普通函数调用替换了所有内联,并且由于这个类被大量使用,我们的代码变得更慢了。

问题是:有没有什么方法可以在使用它的每个库中保持内联调用,但仍然在 dll 之间传递数据并避免警告?

我们使用 Microsoft VC++ 2012 编译器。

最佳答案

根据我的经验,如果速度是个问题,我通过仅使用静态链接代码/ header 实现了更好的性能 inlinefastcall代码而不是 DLL s,正是出于您所描述的原因,但是,回想起来,我认为可能有某种方法可以实现您所说的,尽管我怀疑基准测试仍会显示静态链接代码更快。

我正在研究强制 DLL在加载时驻留在内存中(并且确实可以按照文章 here 执行此操作),以便可以实现与内联/静态链接代码类似的性能。

一开始这似乎可行,但是如果 DLL 所在的内存加载在任何时候被分页,它会变得像访问 DLL 一样慢动态编码。

直到我研究了链接到 DLL 的更多方法s 我个人推荐 inline fastcall 代码(如果这是一个选项),尽管这会导致可执行文件变得更大,并且如果内存占用成为问题可能会影响您的发布。

作为您上面提到的两行的快速修复,您可以尝试更改:

template class __declspec(dllexport) Point<long>;
template class __declspec(dllexport) Point<double>;

extern template class __declspec(dllexport) Point<long>;
extern template class __declspec(dllexport) Point<double>;

这应该有望解决您遇到的问题。 (有关执行此操作的更多信息可用 here,在该页面上用于导出 STL 类或包含 STL 类的对象的实例,这似乎是同一问题)。

然而,内联(编译阶段“优化”)的原则天生就与从 DLL 导出/导入相对立:前者通过将所有内容组合在一个包中来优化速度,后者通过以下方式优化内存占用/模块化将代码分成不同的较小的包,可以在需要时调用。

注意事项:

  1. fastcall将一个或多个参数放入寄存器, 从而减少执行所需的内存调用次数。

    • 对于 MSoft 和 GCC,当您只有 2 个参数时,您可以获得最显着的速度优势。
    • Borland 编译器最多允许使用 3 个寄存器/参数
  2. 另请注意,inline 关键字并不能保证代码会 被内联,这只是一个非常强烈的建议 编译器,但是其他优化标志可以将其删除或内联 您没有标记为内联的其他部分。

希望这对您有所帮助,但一如既往,如果您需要更多信息/帮助,请告诉我。 :)

关于c++ - 如何保持内联调用但避免编译器警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21304930/

相关文章:

c++ - Qt qrc 资源路径不起作用

c++ - Clang vs GCC vs MSVC 模板转换运算符——哪个编译器是对的?

c# - 在 C# 中验证 .NET 程序集?

c++ - 如何使用 visual studio 构建 o2scl?

c++ - 链接到 C++ 中的 DLL - 相同的代码适用于 Visual Studio,但不适用于 MinGW

xml - C++ 在没有 CLR 的情况下读/写 XML

c++ - 使用 unique_ptr 作为我自己的移动构造函数的替代方法是一种好习惯吗?

c++ - 如何在运行时填充 boost::fusion::vector?

c++ - C++中奇怪的char数组输出

c++ - 如何使用 fopen 和文件指针打开多个文件?