【发布时间】:2014-01-23 10:05:40
【问题描述】:
我有一个类,它在我的软件中的所有代码中广泛使用。这个类是带有一些几何函数的点抽象,它是由坐标类型模板化的,例如 long 或 double。如果这一点在动态库之间传递,我会收到编译器警告C4252:类“Point”需要有 dll 接口供“OtherClass”类的客户端使用,但代码运行良好且快速,因为所有库具有相同的编译设置。
由于我们的政策是完全没有警告,我们决定将两个广泛使用的模板特化标记为 dll 导出,如下所示(在带有模板的标题中):
template class __declspec(dllexport) Point<long>;
template class __declspec(dllexport) Point<double>;
但现在编译器将所有内联替换为常用函数调用,并且由于此类被大量使用,我们的代码变得慢得多。
问题是:有没有办法在每个使用它的库中保持内联调用,但仍然在 dll 之间传递数据并避免警告?
我们使用 Microsoft VC++ 2012 编译器。
【问题讨论】:
-
根据我的经验,如果速度是一个问题,我通过使用静态链接代码而不是 DLL 获得了更好的性能,这正是您所描述的原因,但是,回想起来,我认为这可能是实现的某种方式您在说什么,尽管我怀疑基准测试仍会显示静态链接的代码更快。我正在研究强制 dll 在加载时驻留在内存中,以便可以实现与内置/静态链接代码类似的性能。我会在今天晚些时候回复你:)
-
问题不在于将调用从静态更改为动态,而在于将内联函数更改为常用调用函数。一旦您标记了您的类/函数 dll 导出,您将不再获得任何内联函数。
-
是的,这又回到了静态/动态链接:如果它在 DLL 中,你不能在编译时
inline代码,因为编译器不知道函数背后代码的细节。源代码必须在编译时可用以内联到调用位置,此时 dll 变得不必要,因为代码已经在 exe 中。 -
我知道 DLL 使代码更新更加直接,但是对于原始速度必须进行一些权衡:我有
exes 的重量超过 500MB 但是,它们是必需的尽可能快地运行的能力,当速度不是问题并且易于维护/内存占用时,DLL 几乎总能节省一天:) -
类源在编译阶段确实可用,但问题是它在其他DLL之间传递。是的,它有效,但会发出警告。所以我们对当前架构没问题,但我正在考虑警告消失。
标签: c++ visual-c++ dll