c++ cross-platform

¿Las aplicaciones C++ son multiplataforma?



cross-platform (6)

Una de las primeras cosas que aprendí cuando era estudiante fue que las aplicaciones C ++ no se ejecutan en diferentes sistemas operativos. Recientemente, leí que las aplicaciones C ++ basadas en Qt se ejecutan en todas partes. ¿Entonces qué está pasando? ¿Las aplicaciones C ++ son multiplataforma o no?


  1. Código fuente compatible. Si compilo el código fuente, se ejecutará en todas partes.

  2. Compatibilidad API / ABI. ¿El sistema operativo proporciona la interfaz a sus componentes de manera que el código lo entienda?

  3. Compatibilidad binaria ¿El código es capaz de ejecutarse en el host de destino?

Código fuente compatible

C++ es un estándar que define cómo se pueden leer y escribir las estructuras, la memoria y los archivos.

#include <iostream> int main( int argc, char ** argv ) { std::cout << "Hello World" << std::endl; }

El código escrito para procesar datos (p. Ej., grep , awk , sed ) generalmente es multiplataforma.

Cuando desea interactuar con el usuario, los sistemas operativos modernos tienen una GUI, estos no son multiplataforma, y ​​hacen que el código se escriba para una plataforma específica.

Las bibliotecas como qt o wxWidgets tienen implementaciones para múltiples plataformas y le permiten programar para qt lugar de Windows o iOS , y el resultado es compatible con ambas.

El problema con estas bibliotecas anónimas es que eliminan algunos de los beneficios específicos de la plataforma X en aras de la uniformidad en todas las plataformas.

Ejemplos de esto serían en Windows usando la función WaitForMultipleObjects , que le permite esperar que ocurran diferentes tipos de eventos, o la función fork en UNIX, que permite que se ejecuten dos copias de su proceso con un estado compartido significativo. En la interfaz de usuario, las formas se ven y se comportan ligeramente diferente (por ejemplo, selector de color, maximizar, minimizar, la capacidad de rastrear el mouse fuera de su ventana, el comportamiento de los gestos).

Cuando el trabajo que debe realizar es importante para usted, puede terminar queriendo escribir un código específico de la plataforma para aprovechar las ventajas de la aplicación específica.

La biblioteca C sqlite es un código ampliamente multiplataforma, pero su IO de bajo nivel es específico de la plataforma, por lo que puede garantizar la integridad de la base de datos (que los datos realmente se escriben en el disco).

Entonces, las bibliotecas como Qt sí funcionan, pueden producir resultados que no son satisfactorios y terminan escribiendo código nativo.

Compatibilidad API / ABI

Diferentes lanzamientos de UNIX y Windows tienen alguna forma de compatibilidad entre ellos. Éstos permiten construir un binario para que una versión del sistema operativo se ejecute en otras versiones del sistema operativo.

En UNIX, la elección de su máquina de compilación define la compatibilidad. La revisión de sistema operativo más baja que desee admitir debe ser su máquina de compilación, y generará binarios compatibles con las versiones secundarias subsiguientes hasta que hagan un cambio radical (desaprobar una biblioteca).

En Windows y Mac OS X, usted elige un SDK que le permite enfocarse en un conjunto de sistemas operativos con los mismos problemas con los cambios de última hora.

En Linux, cada revisión del kernel es ABI incompatible con cualquier otra, y los módulos del kernel necesitan ser compilados de nuevo para cada revisión del kernel.

Compatibilidad binaria

Esta es la capacidad de la CPU para comprender el código. Esto es más complejo de lo que podría pensar, ya que los chips x64 pueden ser capaces (según el soporte del sistema operativo) de ejecutar el código x86.

Normalmente, un programa C ++ se empaqueta dentro de un contenedor (ejecutable PE, formato ELF) que el sistema operativo usa para descomprimir las secciones de código y datos y cargar bibliotecas. Esto hace que el programa final tenga formas de incompatibilidad tanto binarias (tipo de código) como API (formato del contenedor).

También hoy, si compila una aplicación de Windows x86 (dirigida a Windows 7 en Visual Studio 2015), el código puede no ejecutarse si el procesador no tiene instrucciones SSE2 (aproximadamente 10 años de antigüedad de la CPU).

Finalmente, cuando Apple cambió de PowerPC a x86, proporcionaron una capa de emulación que permitía que el viejo código PowerPC se ejecutara en un emulador en la plataforma x86.

Entonces, en general, la incompatibilidad binaria es un área turbia. Sería posible producir un sistema operativo que identificara instrucciones inválidas (por ejemplo, SSE2) y en la falla, emulado el comportamiento, esto podría actualizarse a medida que aparezcan nuevas características y mantener su código en ejecución, aunque sea binario incompatible.

Incluso si su plataforma es incapaz de ejecutar una forma de conjunto de instrucciones, podría emularse y comportarse de manera compatible.


C ++ es multiplataforma. Puede usarlo para crear aplicaciones que se ejecutarán en muchos sistemas operativos diferentes.

Lo que no es multiplataforma son los compiladores que traducen C ++ en código objeto. Ningún compilador, que yo sepa, tiene todas las características necesarias para que cuando lo use para compilar un programa C ++, se ejecute automáticamente en Windows, Linux y Mac OS.

Qt Creator está integrado con múltiples compiladores y tiene automatización de compilación. Hace que sea fácil cambiar entre diferentes configuraciones y plataformas de destino. Proporciona soporte para construir, ejecutar e implementar aplicaciones C ++ no solo para entornos de escritorio sino también para dispositivos móviles.


C ++ es un lenguaje de programación. Texto. Como tal, no funciona en ninguna parte.

Se espera que el código estándar de C ++ se comporte de igual manera en cualquier plataforma; "multiplataforma" si lo desea. Escribir (estrictamente) la conformidad del código C ++ requiere pedantería porque algunas suposiciones a menudo tienen dependencias en los detalles que son finales para la implementación real y esto se hereda de los objetivos que C ++ busca.

Tenga en cuenta que todavía estamos hablando de código C ++, no de programas C ++. De hecho, cuando pasamos al término "programa", no tenemos más garantías porque ya no estamos hablando de C ++; más bien, la salida del compilador. Aquí es donde la portabilidad comienza a desvanecerse: formato ejecutable, ISA, ABI, rutinas de bajo nivel, etc.
¿Puedes confiar en eso? Si no puede, entonces necesita integrar su programa C ++ en el entorno en el que se ejecutará, recompilando o utilizando elementos específicos de la plataforma.


El estándar C ++ es multiplataforma en el sentido de "escribir una vez, compilar en cualquier lugar", pero no en el sentido de "compilar una vez, ejecutar en cualquier lugar".

Eso significa que si escribe un programa en C ++ estándar, puede compilar y luego ejecutarlo en cualquier entorno de destino que tenga una implementación estándar conforme de C ++.

Sin embargo, no puede compilar su programa en su máquina, enviar el binario y luego esperar que funcione en otros objetivos. (Al menos no en general. Por supuesto, uno puede distribuir binarios del código C ++ bajo ciertas condiciones, pero eso depende del objetivo real. Este es un campo amplio).

Por supuesto, si utiliza características adicionales no estándar, como las matrices de longitud variable de gcc o las bibliotecas de terceros, solo puede compilar en sistemas que proporcionan esas extensiones y bibliotecas.

Algunas bibliotecas como Qt y Boost están disponibles en muchos sistemas (los dos en Linux, Mac y Windows, al menos, creo), por lo que su código se mantendrá multiplataforma si los usa.


Puede lograr que su fuente se compile en varias plataformas, proporcionándole varios binarios de la misma base de origen.

Esto no es "compilar una vez, ejecutar en cualquier lugar con una VM adecuada " como lo hacen Java o C #, sino "escribir una vez, compilar en cualquier lugar con un entorno apropiado " de la forma en que C lo ha hecho todo el tiempo.

Dado que la biblioteca estándar no proporciona todo lo que pueda necesitar, debe buscar bibliotecas de terceros para proporcionar esa funcionalidad. Ciertos frameworks, como Boost, Qt, GTK +, wxWidgets, etc., pueden proporcionar eso. Dado que estos marcos están escritos de una manera que compilan en diferentes plataformas, puede lograr la funcionalidad multiplataforma en el sentido antes mencionado.

Hay varias cosas que debe tener en cuenta si desea que su código C ++ sea multiplataforma.

Lo obvio es la fuente que hace suposiciones sobre los tipos de datos . Su long puede ser de 32 bits aquí y de 64 bits allí. La alineación del tipo de datos y el relleno de estructuras pueden diferir. Hay formas de "ir a lo seguro" aquí, como size_t / size_type / uint16_t , etc., y formas de hacerlo mal, como wchar_t y std::wstring . Se necesita disciplina y algo de experiencia para "hacerlo bien".

No todos los compiladores son creados iguales. No puede usar todas las últimas características del lenguaje C ++, ni usar bibliotecas que dependan de esas características, si necesita que su fuente compile en otros compiladores de C ++. Verifique la tabla de compatibilidad primero.

Otra cosa es endianess . Solo un ejemplo, cuando está escribiendo una secuencia de enteros para archivar en una plataforma (digamos, x86 o x86_64), y luego vuelve a leerla en una plataforma diferente (por ejemplo, ENERGÍA), puede tener problemas. ¿Por qué escribirías enteros para archivar? Bueno, UTF-16 es un número entero ... una vez más, la disciplina y algo de experiencia hacen que esto sea bastante sencillo.

Una vez que haya marcado todos esos cuadros, debe asegurarse de la disponibilidad de las bibliotecas en las que basa su código. Mientras std:: es seguro (pero vea "no todos los compiladores son iguales"), algo tan inocente como boost:: puede convertirse en un problema si mira más allá de la corriente principal. (Ayudé a los chicos de Boost a solucionar uno o dos problemas con respecto a AIX / Visual Age en los últimos años simplemente porque no tenían acceso a esa plataforma para probar nuevas versiones ...)

Ah, y cuidado con los diversos esquemas de licencias que hay. Algunos frameworks que mejoran tus capacidades multiplataforma, como Qt o Cygwin, tienen sus ataduras. Eso no quiere decir que no sean de gran ayuda en las circunstancias correctas, solo que debe estar al tanto de los requisitos de licencia de copyleft / propietario.

Dicho todo esto, está Wine ("Wine no es emulación"), que hace que los ejecutables compilados para Windows se ejecuten en una variedad de sistemas similares a Unix (Linux, OS X, * BSD, Solaris). Existen ciertos límites a sus capacidades, pero cada vez mejora.


Sí. No, quizás. ¿Qué es el código C ++ multiplataforma? El código C ++ multiplataforma es un código que se puede compilar bajo diferentes sistemas de operación sin necesidad de modificarse.

Eso significa que, si usa explícitamente los encabezados que dependen de la plataforma, su código ya no es multiplataforma. Qt resuelve este problema de la siguiente manera: proporcionan envoltorios para todo lo que es específico de la plataforma. Por ejemplo, imagina que estás usando QFile para abrir / leer / escribir un archivo. Tu código se ve como

QFile file(filename); file.open(QFile::ReadOnly); //other stuff

Puede compilar este código en cualquier sistema operativo siempre que tenga un compilador adecuado y bibliotecas Qt para ese sistema operativo. El código oculto en QFile utilizará las funciones de manejo de archivos apropiadas para el sistema operativo, pero eso no debería preocuparlo.

Además, si solo usa la biblioteca estándar, su código se puede compilar en cualquier lugar donde esté presente un compilador de C ++.

Las aplicaciones ya compiladas, sin embargo, no son multiplataforma de manera que, por ejemplo, las aplicaciones Java son, por ejemplo, no se puede compilar una aplicación para Windows y luego ejecutar en Linux, tendrá que volver a compilar su código bajo Linux en su lugar.