Tengo un archivo que contiene lo siguiente:Ocultación de plantillas ejemplificados en la biblioteca compartida creada con g ++
#include <map>
class A {};
void doSomething() {
std::map<int, A> m;
}
Cuando se compila en una biblioteca compartida con g ++, la biblioteca contiene símbolos dinámicos para todos los métodos de std::map<int, A>
. Dado que A
es privado para este archivo, no hay posibilidad de que std::map
se instanciará en cualquier otra biblioteca compartida con los mismos parámetros, por lo que me gustaría ocultar la instanciación de la plantilla (por alguna de las razones descritas en this document).
pensé que debería ser capaz de hacer esto añadiendo una instanciación explícita de la clase de plantilla y marcado como oculto, así:
#include <map>
class A {};
template class __attribute__((visibility ("hidden"))) std::map<int, A>;
void doSomething() {
std::map<int, A> m;
}
Sin embargo, esto no tiene efecto: los símbolos siguen siendo todo exportado. También he intentado que rodea todo el archivo con:
#pragma GCC visibility push(hidden)
...
#pragma GCC visibility pop
pero esto también tiene efecto sobre la visibilidad de los métodos de std::map<int, A>
(aunque sí ocultar doSomething
). Del mismo modo, compilar con -fvisibility=hidden
no tiene ningún efecto sobre la visibilidad de los métodos de std::map<int, A>
.
El documento al que he vinculado anteriormente describe el uso de mapas de exportación para restringir la visibilidad, pero eso parece muy tedioso.
¿Hay alguna manera de hacer lo que quiero en g ++ (aparte de usar mapas de exportación)? Si es así, ¿qué es? De lo contrario, ¿hay alguna buena razón por la cual estos símbolos siempre se deben exportar, o es solo una omisión en g ++?
¿Cómo ve estos símbolos? 'nm -g your_lib.so'? Quiero decir que he hecho el mismo experimento y veo que 'doSomething' tiene una etiqueta' T' u oculta cuando digo 'fvisibility = hidden' pero los símbolos de std :: map siempre tienen la etiqueta' W'. Y el documento dice: 'Las definiciones débiles solo juegan un papel en la vinculación estática'. ¿De qué manera estás usando tu biblioteca? –
He estado usando 'readelf -p .dynstr foo.so'. Gracias por señalar que estos son símbolos débiles. Buscar en Google la "plantilla de símbolo débil" ha producido algunos resultados interesantes, como este: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36022, que no entiendo completamente, pero suena como podría estar estrechamente relacionado. – jchl
Mi interpretación del texto en el documento es que el hecho de que el símbolo sea débil solo es relevante para la vinculación estática, no es que los símbolos débiles solo se utilicen para enlaces estáticos. – jchl