内联和dlimport / dllexport [英] Inline and dlimport/dllexport

查看:272
本文介绍了内联和dlimport / dllexport的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我分析一些旧的代码,这不是我写的。在标头中有很多这样的声明:

  SVPDSDKDLLEXPORT inline C3vec mult(C3vec src,D3DXMATRIX& m); 



如果在SVPDSDK中使用SVPDSDKDLLEXPORT,则定义为_declspec(dllexport) as _declspec(dllimport),如果它在任何项目中使用,它使用SVPDSDK.dll。内联这里似乎很奇怪,因为在标题中没有定义,它是在.cpp文件,但SVPDSDK和所有项目,使用各自的DLL的编译和链接,执行没有任何问题。我假设,它被忽略,函数导出,就像是没有内联。



我发现这个讨论:
C ++:带有dllimport / dllexport的内联函数?



看起来我应该从所有这样的声明中删除inline t内联和出口/进口。但是后来我在MSDN中找到了这个主题:
http://msdn.microsoft。 com / en-us / library / xa0d9ste



我不明白它的某些部分。


您可以使用dllexport属性定义为内联函数。在这种情况下,函数总是实例化和导出,而不管程序中的任何模块是否引用该函数。该函数被假定为由另一个程序导入。


首先,函数总是实例化,是什么意思?我发现只有主题模板函数实例化在C + +,没有任何其他实例化。它是否只与模板连接?



其次,函数总是导出。我不明白它。有可能,在某些情况下不导出具有declspec(_dllexport)的函数吗?


现在关于import:

inline使用dllimport属性声明的函数。在这种情况下,该函数可以扩展(受制于/ Ob规范),但从不实例化。特别地,如果采用内联导入函数的地址,则返回驻留在DLL中的函数的地址。此行为与获取非内联导入函数的地址相同。


同样,我不明白,什么意思在这种情况下实例化。



在写这个问题和从MSDN分析主题时,我做了一个结论,该函数是同时导出/导入和内联的,项目本身(在我的情况下为SVPDSDK),并且在所有导入项目中不是内联的。在MSDN主题中没有明确声明。如果我不导入它在任何项目,它使用它,我没有在其头文件中的定义,它将是一个普通的内联函数,所以我会得到一个链接错误。然后对我来说,它似乎是可以混合内联和导出/导入,认为它与上面提到的stackoverflow讨论的一个答案相矛盾。我对吗?

我还是不明白内联函数实例化的所有这些话。



对不起,我结合了一些问题在一个主题,但我不知道,如何划分它在单独的,因为他们是相同的问题和相同的材料联合。但是,我很感激,如果有人能为我澄清这个问题。

解决方案

事实上, inline 是优化器的一种提示。编译器仍然可以用body生成一个真正的函数,在栈上推送args等。这不会破坏任何逻辑。如果你的inline函数有超过10000行代码,它肯定会这样做。 Microsoft甚至有特殊的 __ forceinline 关键字。猜猜它为什么引入。



函数总是实例化并导出...



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



对于 dllimport ,他们基本上写道: dllimport 阻止在当前二进制模块中生成此内联函数的正文,而内联展开仍然可能。


Now I analyse some old code, which was not written by me. In headers there are many declarations like this:

SVPDSDKDLLEXPORT inline C3vec mult(C3vec src, D3DXMATRIX &m);

SVPDSDKDLLEXPORT is defined as _declspec(dllexport), if it is used in SVPDSDK; as _declspec(dllimport), if it is used in any project, which uses SVPDSDK.dll. Inlining here seems very strange for me as there is no definition in the header, it is in .cpp file, but compilation and linkage of SVPDSDK and all projects, which use respective DLL, are executed without any problems. I assume, that it is just ignored and the function is exported as though is was not inlined.

I've found this discussion: C++ : inline functions with dllimport/dllexport?

Looked like I should have removed "inline" from all such declarations, don't mix inlining and export/import. But then I found this topic in MSDN: http://msdn.microsoft.com/en-us/library/xa0d9ste

I don't understand some parts of it.

You can define as inline a function with the dllexport attribute. In this case, the function is always instantiated and exported, whether or not any module in the program references the function. The function is presumed to be imported by another program.

Firstly, "the function is always instantiated", what does it mean? I've found only topics about template functions instantiation in C++, no any other instantiation. Is it connected only with templates or not?

Secondly, "the function is always exported". I don't understand it at all. Is it possible, that function with declspec(_dllexport) is not exported in some cases? In what cases?

Now about import:

You can also define as inline a function declared with the dllimport attribute. In this case, the function can be expanded (subject to /Ob specifications), but never instantiated. In particular, if the address of an inline imported function is taken, the address of the function residing in the DLL is returned. This behavior is the same as taking the address of a non-inline imported function.

Again, I don't understand, what means instantiation in this case.

While writing this question and analysing topic from MSDN, I made a conclusion, that function, which is exported/imported and inlined at the same time, is inlined only in its project itself (SVPDSDK in my case) and is non-inlined in all importing projects. It's not evidently declared in MSDN topic. If I don't import it in any project, which uses it, and I have not a definition in its header file, it will be an ordinary inlined function, so I will get a linkage error. Then it seems for me that it's agreeable to mix inlining and export/import, thought it contradicts an answer in the stackoverflow discussion, mentioned above. Am I right?
And I still don't understand all this words about inlined functions instantiation.

I'm sorry, that I combined some questions in one topic, but I don't know, how to divide it in separate ones, because they are united by the same issue and the same materials. However, I would be grateful, if anyone could clarify this questions for me.

解决方案

In fact, inline is a sort of hint for the optimizer. Compiler can still generate a real function with body, pushing args on the stack, etc. This will not break any logic. It would definitely do so if your "inline" function would have more than 10000 lines of code. Microsoft even has special __forceinline keyword. Guess why it was introduced.

The function is always instantiated and exported ...

The wording might be not perfect here. Instantiation means here that a body and an entry point will be generated. This has nothing to do with template instantiation. The whole paragraph means that __declspec is more important than inline.

For dllimport they basically write that dllimport prevents generation of body of this inline function in the current binary module, while the inline expansion is still possible.

这篇关于内联和dlimport / dllexport的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆