Windows 中的符号可见性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12717991/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 15:53:26  来源:igfitidea点击:

Symbol Visibility in Windows

c++windowsvisual-c++mingw

提问by André Puel

I do a lot of programming in linux and I use the visibility attribute to define if a symbol is visible or hidden in the Shared Object. Just to make the things clearer possible: If a symbol is visible it will be accessible externally (someone linking with the shared object), if it is hidden it is supposed to be used only internally.

我在 linux 中做了很多编程,我使用可见性属性来定义符号在共享对象中是可见的还是隐藏的。只是为了使事情更清楚:如果符号可见,则可以从外部访问它(与共享对象链接的人),如果它被隐藏,则应该仅在内部使用。

On windows it seems to work a bit different, it works with exporting (the symbol is defined here in the shared object and will be accessible by someone linking with this) and importing (here I am linking with a shared object and the symbol is exported there) symbols. But I couldn't find a way to tell the compiler to not export a symbol because it must be used only here, i.e. if someone link with it a linker error is expected.

在 Windows 上,它似乎有点不同,它适用于导出(符号在此处定义在共享对象中,并且可以被与此链接的人访问)和导入(这里我与共享对象链接并且符号被导出)那里)符号。但是我找不到告诉编译器不要导出符号的方法,因为它必须仅在此处使用,即如果有人链接到它,则会出现链接器错误。

My question is if I can define a symbol as "hidden" (like in linux's gcc) and how. Also, all this visibility in windows topic is a bit fuzzy for me and I was looking for some further reading links to understand better how everything works.

我的问题是我是否可以将符号定义为“隐藏”(如在 linux 的 gcc 中)以及如何定义。此外,Windows 主题中的所有这些可见性对我来说都有些模糊,我正在寻找一些进一步的阅读链接以更好地了解一切是如何工作的。

回答by WeirdlyCheezy

David Rodriguez is correct, in the MSVC environment the programmer typically explicitly exports function/class symbols via the MSVC-specific __declspec(dllexport)modifier. Symbols that aren't explicitly exported shouldn't show up in the symbol table for the compiled DLL (you can use dumpbin, one of the Visual Studio command line utils, to verify, using the /EXPORTS option). It is convention to use dllimport when you import that symbol, although I believe this is optional. How this typically plays out is that header files defining the public interface of a DLL will have some macro that expands to __declspec(dllimport) by default, but is set to expand to __declspec(dllexport) while that library is being built.

David Rodriguez 是对的,在 MSVC 环境中,程序员通常通过特定于 MSVC 的__declspec(dllexport)修饰符显式导出函数/类符号。未显式导出的符号不应显示在已编译 DLL 的符号表中(您可以使用dumpbin,Visual Studio 命令行实用程序之一,使用 /EXPORTS 选项进行验证)。导入该符号时使用 dllimport 是惯例,尽管我认为这是可选的。通常情况下,定义 DLL 公共接口的头文件将具有一些默认情况下扩展为 __declspec(dllimport) 的宏,但在构建该库时设置为扩展为 __declspec(dllexport)。

Note that how GCC and MSVC treat dllexport may be different; perhaps GCC doesn't 'respect' dllexport in the sense of hiding unexported symbols? I would first try compiling with MSVC and test those results with dumpbin before trying the same with GCC. If you don't have Visual Studio, you can still get a MSVC compiler by either downloading VS Express, or (less known) by downloading certain .NET redistributables which ship with command line MSVC (both these options are free and legit). VS Express may be the better choice here so you can get dumpbin.

请注意,GCC 和 MSVC 处理 dllexport 的方式可能不同;也许 GCC 在隐藏未导出的符号的意义上不“尊重”dllexport?我会首先尝试使用 MSVC 进行编译并使用 dumpbin 测试这些结果,然后再使用 GCC 进行相同的尝试。如果您没有 Visual Studio,您仍然可以通过下载 VS Express 或(鲜为人知)通过下载随命令行 MSVC 一起提供的某些 .NET 可再发行组件(这两个选项都是免费且合法的)来获得 MSVC 编译器。VS Express 在这里可能是更好的选择,因此您可以获得 dumpbin。