According to the answer, I had hidden the most internal symbols of a shared library by using the flag -fvisibility=hidden
and the command strip from the building toolchain. But I'd found some symbols, which are used as a standard C++ container's elements, cannot be hidden.
For example,
/* 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;
}
Compiled example1.cpp like this
$ g++ -fPIC -shared -fvisibility=hidden ../example1.cpp -o libexample.so
$ strip -R .comment -R .note libexample.so
And the command nm -D libexample.so | grep Point
return nothing.
Then I replace the C array with the std::vector
,
/* 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;
}
And I compiled example2.cpp like this
$ g++ -fPIC -shared -fvisibility=hidden ../example2.cpp -o libexample.so
$ strip -R .comment -R .note libexample.so
And the command nm -D libexample.so | grep Point
print something like this
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_
It seems because the allocator and the vector of STL are implemented by template. But why this information cannot be hidden?
My compiler is gcc-4.6, os is LMDE MATE Edition.