现在我分析一些旧的代码,这些代码不是我写的。在标题中有许多这样的声明:
SVPDSDKDLLEXPORT inline C3vec mult(C3vec src, D3DXMATRIX &m);
SVPDSDKDLLEXPORT定义为_declspec(dllexport),如果它在SVPDSDK中使用;如_declspec(dllimport),如果它在任何使用SVPDSDK.dll的项目中使用。在这里内联对我来说似乎很奇怪,因为标题中没有定义,它在.cpp文件中,但是SVPDSDK和使用各自DLL的所有项目的编译和链接都没有任何问题地执行。我假设,它只是被忽略而且函数被导出,好像没有内联。
我发现了这个讨论: C++ : inline functions with dllimport/dllexport?
看起来我应该从所有此类声明中删除“内联”,不要混合内联和导出/导入。但后来我在MSDN中找到了这个主题: http://msdn.microsoft.com/en-us/library/xa0d9ste
我不明白它的某些部分。
您可以使用dllexport属性将内联定义为内联函数。在这种情况下,无论程序中的任何模块是否引用该函数,该函数始终被实例化和导出。假定该函数由另一个程序导入。
首先,“函数总是被实例化”,这是什么意思?我在C ++中只找到了关于模板函数实例化的主题,没有任何其他实例。是否仅与模板连接?
其次,“功能总是被导出”。我根本不明白。是否有可能在某些情况下不导出具有declspec(_dllexport)的函数?在什么情况下?
现在关于导入:
您还可以将使用dllimport属性声明的函数定义为内联。在这种情况下,可以扩展该功能(以/ Ob规范为准),但从未实例化。特别是,如果采用内联导入函数的地址,则返回驻留在DLL中的函数的地址。此行为与获取非内联导入函数的地址相同。
同样,我不明白,在这种情况下,实例化是什么意思。
在编写这个问题并从MSDN分析主题时,我得出结论,该函数同时导出/导入和内联,仅在其项目本身(在我的情况下为SVPDSDK)内联并且是非在所有进口项目中内联。它在MSDN主题中没有明确声明。如果我不在任何使用它的项目中导入它,并且我的头文件中没有定义,那么它将是一个普通的内联函数,所以我会得到一个链接错误。然后对我来说,混合内联和导出/导入是合适的,认为它与上面提到的stackoverflow讨论中的答案相矛盾。我是对的吗? 我仍然不理解所有关于内联函数实例化的文字。
对不起,我在一个主题中加入了一些问题,但我不知道,如何将它分开,因为它们是由同一个问题和相同的材料联合起来的。但是,如果有人能为我澄清这些问题,我将不胜感激。
答案 0 :(得分:6)
实际上,inline
是优化器的一种提示。编译器仍然可以使用body生成实际函数,在堆栈上推送args等。这不会破坏任何逻辑。如果你的“内联”函数有超过10000行代码,肯定会这样做。 Microsoft甚至还有特殊的__forceinline
关键字。猜猜它为何被引入。
The function is always instantiated and exported ...
这里的措辞可能并不完美。实例化在此意味着将生成主体和入口点。这与模板实例化无关。整个段落意味着__declspec
比inline
更重要。
对于dllimport
,他们基本上写dllimport
阻止在当前二进制模块中生成此内联函数的主体,而内联扩展仍然可能。