类或函数声明中间的宏
我已阅读相关问题,例如 this 和 this 和其他页面,但它们没有t真的回答我的问题.
I've read related questions like this and this, and other pages, but they don't really answer my question.
基本上,我看到如下代码.
Basically, I see code like the following.
class SOME_MACRO SomeClass{
SomeClass();
~SomeClass();
};
这真的让我很困惑.现在我认为自己对 C++ 相当了解(尽管对预处理器了解较少),但我不记得在我读过的任何书中看到过这样的声明.但是我一直在现实世界中看到这样的代码,例如在 OpenCV.您在书本或课堂上学到的 C++ 与您在实践中实际看到的 C++ 之间似乎存在差异,我觉得这很不幸.
This is really confusing to me. Now I consider myself reasonably knowledgeable about C++ (though less so with the preprocessor), but I don't remember seeing declarations like that in any book I've read. However I see code like this in the real world all the time, for example in OpenCV. There seems to be a discrepancy between the C++ you learn about in a book or in class, and the C++ you actually see in practice, and I find that rather unfortunate.
我从 here 和 这里上面的宏是用来告诉链接器的如何正确链接它,或类似的东西.对于 此处的示例,QuickFAST_Export
被启用进入 __declspec(dllexport)
或 __declspec(dllimport)
.在其他情况下,这些宏会根据系统是 Linux 还是 Windows 来告诉链接器如何操作.我从抽象的角度了解这一切;我知道宏的用途,我知道它们现在做什么,至少大致知道.所以我不想要像那些宏在那里所以你可以改变[...]"这样的答案,因为这些答案并没有告诉我如何在我自己的程序中使用这种声明我自己可能会从头开始写.
I've learnt from here and here that macros like that above are used to tell the linker how to link it properly, or something like that. For the example here, the QuickFAST_Export
gets turned into either __declspec(dllexport)
or __declspec(dllimport)
. In other cases, these macros tell the linker how to behave depending on whether the system is Linux or Windows. I know all this from an abstract perspective; I know what the macros are there for and I know what they do now, roughly at least. So I don't want answers like "those macros are there so you can change the [...]", because those answers don't tell me how I might go about using this kind of declaration myself, in a program that I might write from scratch, myself.
我的问题是,什么时候把像 __declspec(dllimport)
这样的东西放在类声明的中间是合法的?__declspec(dllimport)
是什么实际的东西?int
?一个东西?在 C++ 标准的哪一部分中说这样的类声明是合法的?如果有人可以编写一个最小的程序来说明一个类声明,其中有一个非平凡(非空)宏,它可以编译并且最好做一些可见的事情,那将不胜感激.
My question is, since when was it legal to just put something like __declspec(dllimport)
in the middle of a class declaration anyway? What actual thing is __declspec(dllimport)
? An int
? An object? In which part of the C++ standard does it say that class declarations like this are legal? If someone could write a minimal program illustrating a class declaration with a non-trivial (non-empty) macro in the middle of it, that compiles and preferably does something visible, that would be much appreciated.
推荐答案
我从这里和这里了解到,上面的宏用于告诉链接器如何正确链接它,或者类似的东西.
I've learnt from here and here that macros like that above are used to tell the linker how to link it properly, or something like that.
为了迂腐,它不是告诉链接器如何链接的宏.宏被预处理器简单地替换为定义要替换的任何文本.在您的示例中,它将有条件地替换为 __declspec(dllexport)
或 __declspec(dllimport)
.另一方面,这些 declspec 说明符确实告诉链接器要做什么......至少是一些理解说明符的链接器.
To be pedantic, it's not the macro that tells the linker how to link. The macro is simply replaced by the preprocessor by whatever text it's defined to be replaced with. In the case of your example, it would be conditionally replaced with __declspec(dllexport)
or __declspec(dllimport)
. Those declspec specifiers on the other hand do tell the linker what to do... at least some linker that understands the specifier.
从什么时候开始在类声明的中间放置像 __declspec(dllimport) 这样的东西是合法的?
since when was it legal to just put something like __declspec(dllimport) in the middle of a class declaration anyway?
自从微软实现了他们的编译器并指定它是合法的.根据 c++ 标准,这是不合法的.
Since Microsoft implemented their compiler and specified that it's legal. It's not legal according to the c++ standard.
C++ 标准的哪一部分规定了这样的类声明是合法的?
In which part of the C++ standard does it say that class declarations like this are legal?
它没有.使用这些说明符是非标准的,并且不能保证在 Microsoft 以外的任何其他编译器中工作.这就是为什么在不支持关键字的编译器中使用此类宏时,通常将其定义为扩展为空字符串(或者可能是其他内容,特定于另一个实现).
It doesn't. Using those specifiers is non-standard and not guaranteed to work in any other compiler than Microsoft's. That's why such macro is typically defined to expand to an empty string (or possibly something else, specific to another implementation) when used in a compiler that does not support the keyword.
__declspec(dllimport) 是什么?
What actual thing is __declspec(dllimport)?
这是一个非标准关键字.您可以从他们的 (Microsoft) 文档中找到更多信息.
It is a non-standard keyword. You can find out more from their (Microsoft) documentation.
为了深入一点,关键字告诉链接器在编译共享(动态链接)库时如何导出符号.动态链接是一个与标准完全不同的概念.它是实现定义的.
To dive a little bit deeper, the keywords tell the linker how to export symbols when compiling a shared (dynamically linked) library. Dynamic linking is a concept that's entirely foreign to the standard. It's implementation defined.
我自己如何在自己从头开始编写的程序中使用这种声明.
how I might go about using this kind of declaration myself, in a program that I might write from scratch, myself.
你打算写一个共享库吗?如果没有,那么你不需要知道.如果是,那么您需要阅读您所针对的每个平台的文档.
Do you intend to write a shared library? If not, then you don't need to know. If yes, then you need to read the documentation of every platform that you're targetting.
这是 Microsoft 文档中的演练,可指导您完成创建动态链接库的步骤.
Here is a walkthrough in the Microsoft's documentation that guides you through the steps to create a dynamically linked library.
相关文章