gpt4 book ai didi

c++ - 如果将某个符号的名称用作 STL 容器的元素,为什么我不能隐藏它?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:10:32 25 4
gpt4 key购买 nike

根据answer ,我通过使用标志 -fvisibility=hidden 和构建工具链中的命令 strip 隐藏了共享库的大部分内部符号。但我发现一些用作标准 C++ 容器元素的符号无法隐藏。

例如,

/* example1.cpp */
#include <stdio.h>

#define MY_EXPORTS __attribute__((visibility("default")))

extern "C" {
MY_EXPORTS void* create();
MY_EXPORTS void dosth(void*, int i);
MY_EXPORTS void release(void*);
}

class Point {
public:
int x;
int y;
Point() {
x = -1;
y = -1;
}
Point(int x_, int y_) {
x = x_;
y = y_;
}
int X() const {return x;}
int Y() const {return y;}
};

class ABC {
Point pts[2];
public:
ABC() {
Point pt0(0,0), pt1(1,1);
pts[0] = pt0;
pts[1] = pt1;
}
int getx(int i) { return pts[i].x; }
int gety(int i) { return pts[i].y; }
};


MY_EXPORTS void* create()
{
return new ABC();
}

MY_EXPORTS void dosth(void* handle, int i)
{
ABC* p = (ABC*)handle;
printf("%d,%d\n", p->getx(i), p->gety(i));
}

MY_EXPORTS void release(void* handle)
{
ABC* p = (ABC*)handle;
delete p;
}

像这样编译example1.cpp

$ g++ -fPIC -shared -fvisibility=hidden ../example1.cpp -o libexample.so 
$ strip -R .comment -R .note libexample.so

和命令 nm -D libexample.so | grep Point 什么都不返回。

然后我用 std::vector 替换 C 数组,

/* example2.cpp */
#include <stdio.h>
#include <vector>

#define MY_EXPORTS __attribute__((visibility("default")))

extern "C" {
MY_EXPORTS void* create();
MY_EXPORTS void dosth(void*, int i);
MY_EXPORTS void release(void*);
}

using std::vector;
class Point {
public:
int x;
int y;
Point() {
x = -1;
y = -1;
}
Point(int x_, int y_) {
x = x_;
y = y_;
}
int X() const {return x;}
int Y() const {return y;}
};

class ABC {
vector<Point> pts;
public:
ABC() {
pts.push_back(Point(0,0));
pts.push_back(Point(1,1));
}
int getx(int i) { return pts[i].x; }
int gety(int i) { return pts[i].y; }
};


MY_EXPORTS void* create()
{
return new ABC();
}

MY_EXPORTS void dosth(void* handle, int i)
{
ABC* p = (ABC*)handle;
printf("%d,%d\n", p->getx(i), p->gety(i));
}

MY_EXPORTS void release(void* handle)
{
ABC* p = (ABC*)handle;
delete p;
}

我这样编译example2.cpp

$ g++ -fPIC -shared -fvisibility=hidden ../example2.cpp -o libexample.so 
$ strip -R .comment -R .note libexample.so

和命令 nm -D libexample.so | grep Point 打印这样的东西

000000000000311c W _ZN9__gnu_cxx13new_allocatorI5PointE10deallocateEPS1_m
00000000000030be W _ZN9__gnu_cxx13new_allocatorI5PointE7destroyEPS1_
0000000000003236 W _ZN9__gnu_cxx13new_allocatorI5PointE8allocateEmPKv
0000000000002aba W _ZN9__gnu_cxx13new_allocatorI5PointE9constructEPS1_RKS1_
...
0000000000002dd2 W _ZNSt6vectorI5PointSaIS0_EE3endEv
0000000000002fde W _ZNSt6vectorI5PointSaIS0_EE5beginEv
0000000000002942 W _ZNSt6vectorI5PointSaIS0_EE9push_backERKS0_

好像是因为allocator和STL的vector是用template实现的。但是为什么不能隐藏这些信息呢?

我的编译器是gcc-4.6,操作系统是LMDE MATE Edition

最佳答案

这些是由STL 模板机制创建的函数。这些名称的可见性由 sTL 控制,因此您的代码不会影响它们是否可见。

不清楚您是否只是想减少符号的数量,或者您实际上想从您的共享库中隐藏一个特定的名称 - 例如,如果您有 class MySecretObject,您想要隐藏不同于包含数千个名称的符号表,这让我很烦。

您可能会创建一个隐藏实际名称的包装器类型,但以某种方式,如果您真的想隐藏对象的存在,则需要修改 STL 以不公开它。当然,这也意味着您将需要使用那个特殊的名称[尽管有时巧妙地使用宏可以避免这种情况]。

没有简单/推荐的方法来避免 STL 导出某些符号。那将会发生。如果您使用包装器类型,您可以控制它们的名称,但它不会真正改变导出名称的数量或类型,只会改变暴露的确切名称。

如果您解释您对“我只想导出那些我想导出的内容”的担忧,我会很乐意扩展答案。

编辑:

我相信通过将对象包装在另一个类中可以“隐藏”名称:

class HidePoint
{
public:
Point p;
};

现在,您当然会公开HidePoint,但是如果您将其命名为AW 或类似的名称,那么它就是隐藏的。

或者:

#define Point SomeOtherUniqueName

将使名称隐藏。

关于c++ - 如果将某个符号的名称用作 STL 容器的元素,为什么我不能隐藏它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21361679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com