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