2010-05-27 17 views
10

Tôi có một tập tin có chứa những điều sau đây:Ẩn mẫu thuyết minh trong thư viện chia sẻ tạo với g ++

#include <map> 

class A {}; 

void doSomething() { 
    std::map<int, A> m; 
} 

Khi biên dịch vào một thư viện chia sẻ với g ++, thư viện chứa ký tự động cho tất cả các phương pháp std::map<int, A>. Vì A là riêng tư đối với tệp này, không có khả năng nào std::map sẽ được khởi tạo trong bất kỳ thư viện được chia sẻ nào khác có cùng thông số, vì vậy tôi muốn ẩn bản mẫu (vì một số lý do được mô tả trong this document).

tôi nghĩ rằng tôi sẽ có thể làm điều này bằng cách thêm một instantiation rõ ràng của lớp mẫu và đánh dấu nó như ẩn, như vậy:

#include <map> 

class A {}; 
template class __attribute__((visibility ("hidden"))) std::map<int, A>; 

void doSomething() { 
    std::map<int, A> m; 
} 

Tuy nhiên, điều này không có hiệu lực: những biểu tượng vẫn là tất cả đã xuất. Tôi cũng đã cố gắng bao quanh toàn bộ tập tin với:

#pragma GCC visibility push(hidden) 
... 
#pragma GCC visibility pop 

nhưng điều này cũng không ảnh hưởng đến tầm nhìn của các phương pháp std::map<int, A> (mặc dù nó ẩn doSomething). Tương tự, biên dịch với -fvisibility=hidden không ảnh hưởng đến khả năng hiển thị của các phương thức của std::map<int, A>.

Tài liệu tôi liên kết ở trên mô tả việc sử dụng bản đồ xuất để hạn chế khả năng hiển thị, nhưng điều đó có vẻ rất tẻ nhạt.

Có cách nào để làm những gì tôi muốn trong g ++ (trừ việc sử dụng bản đồ xuất) không? Nếu vậy, nó là cái gì? Nếu không, có một lý do chính đáng tại sao những biểu tượng này phải luôn được xuất khẩu, hay đây chỉ là một thiếu sót trong g ++?

+0

Làm thế nào để bạn nhìn thấy các biểu tượng này? 'nm -g your_lib.so'? Tôi có nghĩa là tôi đã làm thử nghiệm tương tự và thấy rằng 'doSomething' hoặc có thẻ' T' hoặc ẩn khi tôi nói 'fvisibility = hidden' nhưng std :: biểu tượng bản đồ có thẻ' W' luôn. Và tài liệu nói: 'Các định nghĩa yếu chỉ đóng vai trò trong liên kết tĩnh'. Bạn đang sử dụng thư viện của mình theo cách nào? –

+0

Tôi đã sử dụng 'readelf -p .dynstr foo.so'. Cảm ơn bạn đã chỉ ra rằng đây là những biểu tượng yếu. Googling cho "mẫu biểu tượng yếu" đã tạo ra một số kết quả thú vị, chẳng hạn như kết quả này: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36022, điều mà tôi không hiểu hoàn toàn, nhưng có vẻ như nó có thể liên quan chặt chẽ. – jchl

+0

Cách giải thích của tôi về văn bản trong tài liệu là thực tế là biểu tượng yếu chỉ liên quan đến liên kết tĩnh, không phải là các ký hiệu yếu chỉ được sử dụng để liên kết tĩnh. – jchl

Trả lời

10

Từ báo cáo GCC lỗi #36022, là m arked INVALID, Benjamin Kosnik nhận xét:

[A] n lớp ngoại lệ sẽ được ném giữa DSOs phải đánh dấu rõ ràng với tầm nhìn mặc định sao cho 'type_info' nút sẽ được thống nhất giữa DSOs. Vì vậy, lý do cho libstdC++ có không gian tên std có khả năng hiển thị "mặc định".

Ngoài ra, nhìn qua libstdC++ nguồn cho std::map (tôi là trong /usr/include/c++/4.4.4/bits/stl_map.h), dường như cách libstdC++ thực thi tầm nhìn mặc định là với _GLIBCXX_BEGIN_NESTED_NAMESPACE vĩ mô được sử dụng ở đầu stl_map.h:

# define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ (#V))) 
# define _GLIBCXX_BEGIN_NESTED_NAMESPACE(X, Y) _GLIBCXX_BEGIN_NAMESPACE(X) 
# define _GLIBCXX_BEGIN_NAMESPACE(X) namespace X _GLIBCXX_VISIBILITY_ATTR(default) { 

Do đó việc triển khai STL của bạn được ghi đè rõ ràng -fvisibility=hidden#pragma GCC visibility push(hidden)/#pragma GCC visibility pop.

Nếu bạn thực sự muốn để buộc các std::map thành viên để có tầm nhìn ẩn sau đó tôi nghĩ rằng bạn có thể sử dụng một cái gì đó như:

// ensure that default visibility is used with any class that is used as an exception type 
#include <memory> 
#include <new> 
#include <stdexcept> 

// now include the definition of `std::map` using hidden visibility 
#include <bits/c++config.h> 
#undef _GLIBCXX_VISIBILITY_ATTR 
#define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ ("hidden"))) 
#include <map> 
#undef _GLIBCXX_VISIBILITY_ATTR 
#define _GLIBCXX_VISIBILITY_ATTR(V) __attribute__ ((__visibility__ (#V))) // restore `_GLIBCXX_VISIBILITY_ATTR` 

Sau đó, hàng loạt các lệnh sau đây sẽ xác minh rằng std::map<int, A> thành viên có thể bị tước từ một đối tượng chia sẻ:

  1. g++ -c -fPIC -fvisibility=hidden test.cpp
  2. g++ -shared -Wl,-soname,libtest.so.1 -o libtest.so.1.0 test.o
  3. strip -x libtest.so.1.0
  4. readelf -s libtest.so.1.0

Lưu ý rằng trước khi bước 3, readelf -s libtest.so.1.0 in (đối với tôi):

Symbol table '.dynsym' contains 23 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 00000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    2: 00000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    3: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.4 (2) 
    4: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_1.3 (3) 
    5: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.0 (4) 
    6: 00000000  0 FUNC WEAK DEFAULT UND [email protected]_2.1.3 (5) 
    7: 00000d02  5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev 
    8: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt 
    9: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    10: 000023bc  0 NOTYPE GLOBAL DEFAULT ABS _end 
    11: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS _edata 
    12: 00000d5e  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    13: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS __bss_start 
    14: 00000bac  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    15: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    16: 000007f4  0 FUNC GLOBAL DEFAULT 10 _init 
    17: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 
    18: 00000df8  0 FUNC GLOBAL DEFAULT 13 _fini 
    19: 00000dba  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    20: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev 
    21: 00000d90  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    22: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 

Symbol table '.symtab' contains 84 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 000000f4  0 SECTION LOCAL DEFAULT 1 
    2: 00000118  0 SECTION LOCAL DEFAULT 2 
    3: 000001c0  0 SECTION LOCAL DEFAULT 3 
    4: 0000022c  0 SECTION LOCAL DEFAULT 4 
    5: 0000039c  0 SECTION LOCAL DEFAULT 5 
    6: 000006b6  0 SECTION LOCAL DEFAULT 6 
    7: 000006e4  0 SECTION LOCAL DEFAULT 7 
    8: 00000754  0 SECTION LOCAL DEFAULT 8 
    9: 0000077c  0 SECTION LOCAL DEFAULT 9 
    10: 000007f4  0 SECTION LOCAL DEFAULT 10 
    11: 00000824  0 SECTION LOCAL DEFAULT 11 
    12: 00000930  0 SECTION LOCAL DEFAULT 12 
    13: 00000df8  0 SECTION LOCAL DEFAULT 13 
    14: 00000e14  0 SECTION LOCAL DEFAULT 14 
    15: 00000ef8  0 SECTION LOCAL DEFAULT 15 
    16: 00001240  0 SECTION LOCAL DEFAULT 16 
    17: 0000225c  0 SECTION LOCAL DEFAULT 17 
    18: 00002264  0 SECTION LOCAL DEFAULT 18 
    19: 0000226c  0 SECTION LOCAL DEFAULT 19 
    20: 00002270  0 SECTION LOCAL DEFAULT 20 
    21: 00002358  0 SECTION LOCAL DEFAULT 21 
    22: 00002364  0 SECTION LOCAL DEFAULT 22 
    23: 000023ac  0 SECTION LOCAL DEFAULT 23 
    24: 000023b4  0 SECTION LOCAL DEFAULT 24 
    25: 00000000  0 SECTION LOCAL DEFAULT 25 
    26: 00000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    27: 0000225c  0 OBJECT LOCAL DEFAULT 17 __CTOR_LIST__ 
    28: 00002264  0 OBJECT LOCAL DEFAULT 18 __DTOR_LIST__ 
    29: 0000226c  0 OBJECT LOCAL DEFAULT 19 __JCR_LIST__ 
    30: 00000930  0 FUNC LOCAL DEFAULT 12 __do_global_dtors_aux 
    31: 000023b4  1 OBJECT LOCAL DEFAULT 24 completed.5942 
    32: 000023b8  4 OBJECT LOCAL DEFAULT 24 dtor_idx.5944 
    33: 000009b0  0 FUNC LOCAL DEFAULT 12 frame_dummy 
    34: 00000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    35: 00002260  0 OBJECT LOCAL DEFAULT 17 __CTOR_END__ 
    36: 0000123c  0 OBJECT LOCAL DEFAULT 15 __FRAME_END__ 
    37: 0000226c  0 OBJECT LOCAL DEFAULT 19 __JCR_END__ 
    38: 00000dc0  0 FUNC LOCAL DEFAULT 12 __do_global_ctors_aux 
    39: 00000000  0 FILE LOCAL DEFAULT ABS test.cpp 
    40: 00000d64  8 FUNC LOCAL HIDDEN 12 _ZNKSt8_Rb_treeIiSt4pairI 
    41: 000023b0  4 OBJECT LOCAL HIDDEN 23 DW.ref.__gxx_personality_ 
    42: 00000b40 11 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    43: 00000bc8 129 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    44: 00000bb1 11 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    45: 00000b4c 96 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    46: 00000ca0 62 FUNC LOCAL HIDDEN 12 _ZNKSt8_Rb_treeIiSt4pairI 
    47: 00000ab2 19 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    48: 00002364  0 OBJECT LOCAL HIDDEN ABS _GLOBAL_OFFSET_TABLE_ 
    49: 00000a56 92 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    50: 000009ec 30 FUNC LOCAL HIDDEN 12 _Z11doSomethingv 
    51: 00000c6e 49 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    52: 00000a32 35 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    53: 000023ac  0 OBJECT LOCAL HIDDEN 23 __dso_handle 
    54: 00000a0a 19 FUNC LOCAL HIDDEN 12 _ZNSt3mapIi1ASt4lessIiESa 
    55: 00002268  0 OBJECT LOCAL HIDDEN 18 __DTOR_END__ 
    56: 00000bbc 11 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    57: 00000a1e 19 FUNC LOCAL HIDDEN 12 _ZNSt3mapIi1ASt4lessIiESa 
    58: 00000d2c 50 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    59: 00000aea 85 FUNC LOCAL HIDDEN 12 _ZNSt8_Rb_treeIiSt4pairIK 
    60: 000009e7  0 FUNC LOCAL HIDDEN 12 __i686.get_pc_thunk.bx 
    61: 00002270  0 OBJECT LOCAL HIDDEN ABS _DYNAMIC 
    62: 00000d02  5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev 
    63: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 
    64: 00000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    65: 00000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    66: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBCXX_3.4 
    67: 00000df8  0 FUNC GLOBAL DEFAULT 13 _fini 
    68: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt 
    69: 00000dba  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    70: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev 
    71: 00000d5e  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    72: 00000d90  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    73: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS __bss_start 
    74: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    75: 00000bac  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    76: 000023bc  0 NOTYPE GLOBAL DEFAULT ABS _end 
    77: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS _edata 
    78: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 
    79: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]@CXX 
    80: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GCC_3.0 
    81: 00000000  0 FUNC WEAK DEFAULT UND [email protected]@GLIBC_2.1 
    82: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    83: 000007f4  0 FUNC GLOBAL DEFAULT 10 _init 

Và sau đó:

Symbol table '.dynsym' contains 23 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 00000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    2: 00000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    3: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.4 (2) 
    4: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_1.3 (3) 
    5: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]_3.0 (4) 
    6: 00000000  0 FUNC WEAK DEFAULT UND [email protected]_2.1.3 (5) 
    7: 00000d02  5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev 
    8: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt 
    9: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    10: 000023bc  0 NOTYPE GLOBAL DEFAULT ABS _end 
    11: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS _edata 
    12: 00000d5e  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    13: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS __bss_start 
    14: 00000bac  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    15: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    16: 000007f4  0 FUNC GLOBAL DEFAULT 10 _init 
    17: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 
    18: 00000df8  0 FUNC GLOBAL DEFAULT 13 _fini 
    19: 00000dba  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    20: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev 
    21: 00000d90  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    22: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 

Symbol table '.symtab' contains 51 entries: 
    Num: Value Size Type Bind Vis  Ndx Name 
    0: 00000000  0 NOTYPE LOCAL DEFAULT UND 
    1: 000000f4  0 SECTION LOCAL DEFAULT 1 
    2: 00000118  0 SECTION LOCAL DEFAULT 2 
    3: 000001c0  0 SECTION LOCAL DEFAULT 3 
    4: 0000022c  0 SECTION LOCAL DEFAULT 4 
    5: 0000039c  0 SECTION LOCAL DEFAULT 5 
    6: 000006b6  0 SECTION LOCAL DEFAULT 6 
    7: 000006e4  0 SECTION LOCAL DEFAULT 7 
    8: 00000754  0 SECTION LOCAL DEFAULT 8 
    9: 0000077c  0 SECTION LOCAL DEFAULT 9 
    10: 000007f4  0 SECTION LOCAL DEFAULT 10 
    11: 00000824  0 SECTION LOCAL DEFAULT 11 
    12: 00000930  0 SECTION LOCAL DEFAULT 12 
    13: 00000df8  0 SECTION LOCAL DEFAULT 13 
    14: 00000e14  0 SECTION LOCAL DEFAULT 14 
    15: 00000ef8  0 SECTION LOCAL DEFAULT 15 
    16: 00001240  0 SECTION LOCAL DEFAULT 16 
    17: 0000225c  0 SECTION LOCAL DEFAULT 17 
    18: 00002264  0 SECTION LOCAL DEFAULT 18 
    19: 0000226c  0 SECTION LOCAL DEFAULT 19 
    20: 00002270  0 SECTION LOCAL DEFAULT 20 
    21: 00002358  0 SECTION LOCAL DEFAULT 21 
    22: 00002364  0 SECTION LOCAL DEFAULT 22 
    23: 000023ac  0 SECTION LOCAL DEFAULT 23 
    24: 000023b4  0 SECTION LOCAL DEFAULT 24 
    25: 00000000  0 SECTION LOCAL DEFAULT 25 
    26: 00000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    27: 00000000  0 FILE LOCAL DEFAULT ABS crtstuff.c 
    28: 00000000  0 FILE LOCAL DEFAULT ABS test.cpp 
    29: 00000d02  5 FUNC WEAK DEFAULT 12 _ZNSt4pairIKi1AED1Ev 
    30: 00000c4a 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 
    31: 00000000  0 NOTYPE WEAK DEFAULT UND __gmon_start__ 
    32: 00000000  0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses 
    33: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GLIBCXX_3.4 
    34: 00000df8  0 FUNC GLOBAL DEFAULT 13 _fini 
    35: 00000d6c 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEEC1ISt 
    36: 00000dba  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    37: 00000cde 35 FUNC WEAK DEFAULT 12 _ZNSaISt4pairIKi1AEED1Ev 
    38: 00000d5e  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    39: 00000d90  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    40: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS __bss_start 
    41: 00000d96 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    42: 00000bac  5 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    43: 000023bc  0 NOTYPE GLOBAL DEFAULT ABS _end 
    44: 000023b4  0 NOTYPE GLOBAL DEFAULT ABS _edata 
    45: 00000ac6 35 FUNC WEAK DEFAULT 12 _ZNSaISt13_Rb_tree_nodeIS 
    46: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]@CXX 
    47: 00000000  0 FUNC GLOBAL DEFAULT UND [email protected]@GCC_3.0 
    48: 00000000  0 FUNC WEAK DEFAULT UND [email protected]@GLIBC_2.1 
    49: 00000d08 35 FUNC WEAK DEFAULT 12 _ZN9__gnu_cxx13new_alloca 
    50: 000007f4  0 FUNC GLOBAL DEFAULT 10 _init 

Xem thêm:

+1

Tôi đã tìm thấy báo cáo lỗi đó và chỉ xem xét các tệp tiêu đề C++, nhưng ý tưởng định nghĩa lại _GLIBCXX_VISIBILITY_ATTR đã không xảy ra với tôi. Nó khá là ác, nhưng tôi có thể thử. Cảm ơn. – jchl

+0

GCC của tôi là 4.6, tôi thấy macro * _GLIBXX_VISIBILITY_ATTR * được đổi tên thành * _GLIBXX_VISIBILITY *. Và macro này phải được định nghĩa lại là '#define _GLIBCXX_VISIBILITY (V)' thay vì '#define _GLIBCXX_VISIBILITY (V) __attribute __ ((__ visibility __ (" hidden ")))', nếu không thì có thể có lỗi liên kết như * undefined reference to ' std :: __ throw_bad_alloc() '*. –

0

Disclaimer: Tôi không phải là một nhà phát triển GCC, và do đó đây là một WAG đầy đủ (wild-ass đoán):

Tôi đoán sẽ là GCC luôn xuất khẩu các định nghĩa mẫu, để cho phép các mối liên kết để loại bỏ các bản sao mẫu. Nếu nó không được xuất và nhiều hơn một lần tệp nguồn đã sử dụng mẫu đó, toàn bộ nguồn cho lớp std::map<k, v> sẽ được sao chép trong hai tệp.

Tôi nghĩ bạn thực sự chú ý nhiều hơn điều này hơn là xứng đáng. Xuất khẩu là một chi tiết triển khai trong C++. Trong C, có nghĩa là không xuất các chức năng nội bộ để khách hàng không dựa vào chúng. Nhưng trong C++, các hàm được xuất khẩu không bao giờ phải liên quan đến mã nguồn. Một phiên bản std::map<k, v> của GCC có thể hoàn toàn khác với các phiên bản khác 'và kết quả là hai tệp nhị phân sẽ không tương thích với liên kết.

Nếu bạn hoàn toàn cần tính di động, hãy xuất giao diện C và bỏ qua các chi tiết cụ thể về C++ được xuất. Bất kỳ khách hàng nào trong thư viện của bạn đang cố gắng gọi các hàng xuất khẩu đó hoặc làm bất cứ điều gì với họ đáng bị sụp đổ và đốt cháy để gọi các chi tiết thực hiện nội bộ rõ ràng.

CHỈNH SỬA: Được tạo CW vì tôi không hoàn toàn 100%.

+1

Lý do tôi muốn ẩn các ký hiệu này không thực sự ngăn người dùng thư viện từ gọi chúng, nhưng để giảm kích thước của tập tin .so. Chúng tôi sử dụng trình tạo mã kết quả trong các thư viện có hàng nghìn biểu tượng được xuất loại này, thêm hàng trăm kB vào kích thước của các bảng ký hiệu động. Giảm số lượng các ký hiệu xuất khẩu sẽ tiết kiệm cho chúng ta rất nhiều không gian đĩa và bộ nhớ, cũng như cải thiện thời gian tải và cho phép trình biên dịch tạo ra mã hiệu quả hơn. – jchl

+0

@jchl: Bạn đang tối ưu hóa vi mô ở đây. Tôi sẽ không lo lắng về nó bởi vì khi một thực thi được tạo ra những danh sách xuất khẩu sẽ được gỡ bỏ anyway. –

+3

Tôi đang xây dựng thư viện được chia sẻ chứ không phải tệp thực thi. Trong hầu hết các môi trường, điều này thực sự là tối ưu hóa vi mô không cần thiết, nhưng do lượng lớn mã được tạo ra và việc sử dụng nhiều mẫu, tối ưu hóa này có khả năng tiết kiệm cho chúng tôi nhiều MB dung lượng đĩa và RAM, cả hai ở mức cao. Bên cạnh đó, tại thời điểm này tôi chỉ muốn biết tại sao tôi không thể làm việc này. – jchl

0

Có thể bạn có thể sử dụng objcopy với tùy chọn --strip-symbol?

Các tùy chọn được mô tả trong objcopy man page

này có thể nhận được tẻ nhạt mặc dù ...

+0

Tùy chọn đó không có vẻ tốt hơn là sử dụng bản đồ xuất.Vì đây là mã được tạo nên, lý tưởng là tôi muốn một giải pháp chỉ liên quan đến việc sửa đổi mã nguồn và không sử dụng các công cụ bổ sung. – jchl

+0

Ồ, tôi không đọc câu hỏi của bạn một cách cẩn thận như tôi cần. Xin lỗi ... –

0

Trong C++, nếu một đối số mẫu có khả năng hiển thị giới hạn, hạn chế này được truyền ngầm đến bản mẫu.

#include <map> 

class __attribute__((visibility ("hidden"))) A {}; 

void doSomething() { 
    std::map<int, A> m; 
} 

nên thực hiện công việc.

- chỉnh sửa -
Một điều nữa, `#pragma khả năng hiển thị GCC 'chỉ ảnh hưởng đến khai báo không gian tên. thành viên lớp và mẫu chuyên ngành không bị ảnh hưởng (Visibility pragmas)

+1

Tôi vừa thử điều này, và thật đáng buồn là nó dường như không có bất kỳ ảnh hưởng nào đến khả năng hiển thị của mẫu được tạo ra. – jchl

+0

Arf bạn nói đúng. Có vẻ như khả năng hiển thị stl được thực thi. Điều này có thể hữu ích http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36022. – log0

2

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36022: The std::namespace is supposed to be exposed and is marked as such in the libstdc++ headers.

Đối với

#undef _GLIBCXX_VISIBILITY_ATTR 

đây là một trích dẫn:

If you were to hack in support for allowing namespace std to have hidden visibility, and run the testsuite with -fvisibility=hidden (see attached patch) you would notice the breakdown in testresults, with mass failures.

Các vấn đề liên quan