限制静态库中符号的可见性 (MSVC/Visual C++)
Limit visibility of symbols in static library (MSVC/Visual C++)
gcc 有一个 -fvisibility 选项,您可以在其中定义哪些函数对链接到您的库的任何人"可见"。虽然这主要用于共享库,但它似乎也可以用于静态库(请参阅如何将 -fvisibility 选项应用于静态库中的符号?
是否可以阻止某些功能可供使用我的库和 MSVC 的用户使用?我不希望我的"内部"函数都位于单个翻译单元中,因此"静态"或使用匿名命名空间将不起作用(AFAIK(。
我怎样才能做到这一点?请注意,我特别指的是使用 MSVC 构建的静态 .lib 库。
谢谢
编辑:我正在与其他人共享我的图书馆,因此这就是为什么我想隐藏某些符号。
不,这是不可能的。Windows"LIB"文件只是OBJ文件(翻译单元,TU(的集合。您可以使用LIB.EXE /EXTRACT:member.obj Library.LIB
来查看这些部分。您的客户会将他们的 TU 和您的 TU 链接在一起。这还包括您的 TU相互链接的部分。
有了你的计划,就不可能将你的TU相互链接起来。您的 TU 要么其符号可见,要么不可见。
你可能想看看MSVC的Unity/Jumbo版本。
虽然我不是 gcc 和 MSVC 链接器选项的专家,但我想我可以给你一个明智的答案:
共享链接和静态链接是非常不同的概念。共享链接是在运行或加载时针对特殊准备的符号(即函数(完成的。共享链接不是标准化的,大多数编译器都要求程序员在运行/加载时显式标记稍后应链接到的函数/符号。 静态链接是在编译或链接时链接。(编译<链接><加载>
<运行时。"> 共享库更像是一个可执行文件,通过将一个符号设为公开或非隐藏,或导出,你说"这个符号将被这个共享库的用户使用",所以编译器做了准备,可以很容易地调用它。此共享函数可能使用对象文件或静态库/存档中的其他符号。共享符号未传递使用的符号将被省略,即不会复制到共享库中(.so .dll(
据我了解,gcc 为静态库/符号提供的隐藏功能似乎是公正的,以防止 gcc 将共享符号使用的内部/静态非标记符号标记为共享可链接。
但是,您仍然可以在此共享库的正文中找到这些内部符号(如果使用(。然而,它们通常不能像"官方"出口符号那样简单地使用。通常,您使用的代码将在使用它的程序中。您可以尝试混淆函数或符号的名称,通常由于您不会将标头分发到此内部符号,因此人们将很难正确猜测 ABI 或 API。但是使用简单的反汇编器作为逆向工程工具仍然是可能的。
然而,我推荐另一种策略:C++知道"内联"的概念,通过说编译器不生成额外的对象文件,而只是将函数的主体复制到使用它的人中,您将很难识别此函数,并且如果不进行修改,它将无法从 extern 调用(因为它缺少被调用者的机器代码(
如果冒昧地给你一个例子,它也演示了 gcc 隐藏标志如何不适用于静态符号:
#include <cstdio>
#if __GNUC__ >= 4
#define hidden __attribute__ ((visibility ("hidden")))
#else
#define hidden
#endif
hidden int hidden_func(int x, int y) {
return x * y;
}
inline int hidden_func2(int x, int y) {
return x * y;
}
int normal_func(int x, int y) {
return hidden_func(x,y) * hidden_func2(x,y);
}
int main()
{
int x{}, y{};
std:: scanf("%d %d", &x, &y);
std::printf("%dn", normal_func(x,y));
std::printf("%dn", hidden_func(x,y));
}
在生成的机器代码中,https://godbolt.org/z/tFpdpE 发布在这里,您将看到只有hidden_func2
在 gcc 和 clang 二进制文件中不可见为符号,但是,由于inline
标志只是编译器的提示,它仍然可以在 MSVC 二进制文件中找到。
- MSVC(Visual C++)是否有等效的-weffc ++?
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- Cmake:为 C 设置警告级别,并为 MSVC 单独设置C++代码(Visual C++)
- 限制静态库中符号的可见性 (MSVC/Visual C++)
- visual MSVC cl.exe尝试使用C++标头范例(定义与声明)
- 为什么MSVC(Visual C++)需要单独的dllimport和dllexport属性,而gcc不需要
- C++模块(MSVC)中的visual Forward声明
- 安装生成工具后找不到Visual Studio代码MSVC cl.exe
- 如何修复MSVC++(Microsoft Visual studio)中"macro overloading"的可变参数宏相关问题?
- Visual MSVC C 调用GFORTRAN子例程
- Visual C++ 模板代码适用于 MSVC 2015,但不适用于 2017
- Visual MSVC C++ 17 获取词汇规范化路径
- ERF在Visual Studio MSVC中的准确性是多少
- MSVC 19.11 / Visual C 2017:尺寸1和size_t类型的初始化列表误解
- visual C++默认特殊成员函数的多个版本——MSVC 2015中的错误
- visual x86-64 MSVC++/Intel C++更改int、long等的大小
- visual MSVC编译器错误C2688:Microsoft C++ABI角大小写问题
- Microsoft Visual c++ 2010 x64跨工具与msvc++可重新分发的差异
- 是否有可能使用编译与MSVC没有Visual Studio
- visual MSVC汇编函数参数