2012-08-13 71 views
4

现在我分析一些旧代码,这些代码不是由我写的。在标头有许多声明这样的:Inline和dlimport/dllexport

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讨论中的答案相矛盾。我对吗?
而我仍然不明白关于内联函数实例化的所有这些词。

对不起,我在一个主题中合并了一些问题,但我不知道如何将它分成不同的部分,因为它们由相同的问题和相同的材料联合起来。不过,如果有人能为我澄清这个问题,我将不胜感激。

+1

当MS文档看起来很荒谬时,总的来说这是因为它是荒谬的。他们的技术作家并不总是很了解这个主题。我认为WinMain是Win32程序的机器代码级入口点的臭名昭着的描述,但我最近没有检查过。 – 2012-08-13 01:18:35

+2

实例化是指生成代码,就好像该函数不在线一样。 – 2012-08-13 01:51:32

回答

6

实际上,inline是优化器的一种提示。编译器仍然可以通过主体生成一个真正的函数,在堆栈上推送参数等。这不会破坏任何逻辑。如果你的“内联”函数有超过10000行代码,它肯定会这样做。微软甚至有特殊的__forceinline关键字。猜猜它为什么被引入。

The function is always instantiated and exported ...

措辞可能是不完美的在这里。实例化意味着将生成一个主体和一个入口点。这与模板实例无关。整段意思是__declspecinline更重要。

对于dllimport他们基本上写道dllimport防止在当前二进制模块中产生这个内联函数的主体,而内联扩展仍然是可能的。

+0

现在我认为,我理解除了你的话以外的所有内容“对于dllimport,他们基本上写道,指定dllimport与未指定dllimport相同。”正如我现在所理解的那样,如果我指定'dllimport'和'inline',那么函数将被展开或动态链接将被执行(由编译器决定)。所以,如果我没有指定'dllimport',函数可以被扩展或者只是以正常的方式实例化(与DLL和导出的函数没有连接)。有区别,不是吗? – 2012-08-13 13:49:57

+0

你的理解是正确的,我在最后一句中的措辞很糟糕。我更新了我的帖子。 – 2012-08-13 16:00:20