for compile c++ c++11 clang libstdc++ libc++

compile - Utilizando bibliotecas compiladas libstdc++ con clang++-stdlib=libc++



llvm 3.7 1 (1)

Estoy trabajando en C ++ con Mac OS X (10.8.2) y recientemente surgió la necesidad de utilizar las características de C ++ 11, que están disponibles a través del compilador de clang ++ que utiliza el libc ++ stdlib. Sin embargo, también necesito usar alguna biblioteca heredada compilada y vinculada contra libstdc ++ (proveniente de MacPorts).

Al hacerlo, obtuve errores de enlace, ya que los encabezados de las bibliotecas heredadas que usan, por ejemplo, std::string , deben resolverse frente a std::__1::basic_string (es decir, la implementación de libc ++ de std::string ) en lugar de la implementación std::basic_string .

¿Hay alguna manera de mezclar las dos bibliotecas en desarrollo (por ejemplo, mediante el uso de algunos indicadores de preprocesadores?)


Lo que está viendo es el uso de espacios de nombres en línea para lograr versiones de ABI.

Lo que eso significa:

Libstdc ++ std::string es una estructura de datos diferente que libc ++ std::string . El primero es un diseño de referencia contado, mientras que el segundo no. Aunque son compatibles con API, no son compatibles con ABI. Eso significa que si construyes una std::string con libstdc ++, y luego la pasas a otro código que está vinculado contra libc ++, el código de recepción pensaría que tiene una libc ++ std::string . Es decir, el receptor no tendría ni idea de que debería aumentar o disminuir los recuentos de referencia.

Sin espacios de nombres en línea, el resultado sería un error de tiempo de ejecución. Lo mejor que puedes esperar es un choque. Con espacios de nombres en línea, este error de tiempo de ejecución se traduce en un error de tiempo de enlace.

Para usted, el programador libstdc ++ std::string y libc ++ std::string parecen del mismo tipo. Pero para el enlazador, parecen tipos completamente diferentes (la clave es el std::__1 nombre std::__1 ). Y la vista del enlazador es correcta. Son tipos completamente diferentes.

Así que sí, puedes manipular algunas banderas de preprocesador para hacer que las cosas se vinculen. Pero entonces tendrías un demonio de tiempo depurando los errores de tiempo de ejecución resultantes.

La única forma de hacer lo que desea hacer es hacer que las interfaces entre estos dylibs no involucren std:: tipos tales como string . Por ejemplo, podría pasar matrices de char lugar. Incluso puede transferir la propiedad de memoria de libstdc ++ - código vinculado a libc ++ - código vinculado y viceversa (ambos pasarán al mismo grupo malloc).