from c++ c include

call c from c++



¿Por qué crear un directorio include/en proyectos C y C++? (3)

1. .hpp y .cpp no ​​necesariamente tienen una relación de 1 a 1, puede haber múltiples .cpp usando la misma .hpp de acuerdo con diferentes condiciones (por ejemplo: diferentes entornos), por ejemplo: una biblioteca multiplataforma, imagine que hay una clase para obtener la versión de la aplicación, y el encabezado es así:

Utilidades.h

#include <string.h> class Utilities{ static std::string getAppVersion(); }

main.cpp

#include Utilities.h int main(){ std::cout << Utilities::getAppVersion() << std::ends; return 0; }

puede haber un .cpp para cada plataforma, y ​​el .cpp puede ubicarse en diferentes ubicaciones para que la plataforma correspondiente pueda seleccionarlos fácilmente, por ejemplo:

.cpp para iOS (ruta: DemoProject / ios / Utilities.cpp):

#include "Utilities.h" std::string Utilities::getAppVersion(){ //some objective C code }

.cpp para Android (ruta: DemoProject / android / Utilities.cpp):

#include "Utilities.h" std::string Utilities::getAppVersion(){ //some jni code }

y por supuesto 2 .cpp no ​​se utilizaría al mismo tiempo normalmente.

2.

#include "file.h"

en lugar de

#include "include/file.h"

le permite mantener el código fuente sin cambios cuando sus encabezados ya no están en la carpeta "incluir".

Cuando trabajo en mis proyectos personales de C y C ++, generalmente pongo file.h y file.cpp en el mismo directorio y luego file.cpp puede hacer referencia a file.h con una directiva #include "file.h" .

Sin embargo, es común encontrar bibliotecas y otros tipos de proyectos (como el kernel de Linux y freeRTOS) donde todos los archivos .h se encuentran dentro de un directorio include/ , mientras que los archivos .cpp permanecen en otro directorio. En esos proyectos, los archivos .h también se incluyen con #include "file.h" lugar de #include "include/file.h" como esperaba.

Tengo algunas preguntas sobre todo esto:

  1. ¿Cuáles son las ventajas de esta organización de estructura de archivos?
  2. ¿Por qué los archivos .h incluidos include/ incluyen con #include "file.h" lugar de #include "include/file.h" ? Sé que el truco real está dentro de Makefile, pero ¿es realmente mejor hacerlo de esa manera en lugar de dejar en claro (en código) que el archivo que queremos incluir está realmente en el directorio include/ ?

La razón principal para hacer esto es que las bibliotecas compiladas necesitan encabezados para ser consumidas por el usuario final. Por convención, los contenidos del directorio de include son los encabezados expuestos para el consumo público. El directorio de origen puede tener encabezados para uso interno, pero no están destinados a ser distribuidos con la biblioteca compilada.

Por lo tanto, al usar la biblioteca, usted se vincula al binario y agrega el directorio de include la biblioteca a las rutas de encabezado de su sistema de compilación. De manera similar, si instala su biblioteca compilada en una ubicación centralizada, puede indicar qué archivos deben copiarse en la ubicación central (los binarios compilados y el directorio de include ) y qué archivos no (el directorio de origen, etc.).


Solía ​​ser que el estilo <header> incluye era del tipo de ruta implícita, es decir, se encuentra en la ruta de la variable de entorno includes o una macro de compilación, y el estilo de "header" incluye fue de la forma explícita, como en , exactamente en relación a donde quiera que esté el archivo fuente que lo incluyó. Si bien algunas cadenas de herramientas de compilación aún permiten esta distinción, a menudo tienen una configuración predeterminada que la anula de manera efectiva.

¿Su pregunta es interesante porque hace surgir la pregunta de cuál es realmente mejor, implícita o explícita? La forma implícita es ciertamente más fácil porque:

  1. Agrupaciones convenientes de encabezados relacionados en jerarquías de directorios.
  2. Solo necesita incluir algunos directorios en la ruta de inclusión y no es necesario que conozca todos los detalles con respecto a las ubicaciones exactas de los archivos. Puede cambiar las versiones de las bibliotecas y sus encabezados relacionados sin cambiar el código.
  3. DRY
  4. ¡Flexible! Su entorno de compilación no tiene que coincidir con el mío, pero a menudo podemos obtener casi los mismos resultados.

Explícita por otro lado tiene:

  1. Construcciones repetibles. Una reordenación de las rutas en una variable de macro / entorno includes , no cambia los archivos de encabezado resultantes encontrados durante la compilación.
  2. Construcciones portátiles. Simplemente empaque todo desde la raíz de la compilación y envíelo a otro desarrollador.
  3. Proximidad de la información. Usted sabe exactamente dónde está el encabezado con #include "/X/Y/Z" . En la forma implícita, es posible que tenga que buscar múltiples rutas e incluso encontrar varias versiones del mismo archivo, ¿cómo sabe cuál se usa en la compilación?

Los constructores han estado discutiendo sobre estos dos enfoques durante muchas décadas, pero una forma híbrida de los dos, en su mayoría triunfa debido al esfuerzo requerido para mantener construcciones basadas únicamente en la forma explícita, y la dificultad obvia que uno podría tener es familiarizarse con el código. De una naturaleza puramente implícita. En general, todos entendemos que nuestras diversas cadenas de herramientas ponen ciertas bibliotecas y encabezados comunes en ubicaciones particulares, de manera que pueden compartirse entre usuarios y proyectos, por lo que esperamos encontrar encabezados C / C ++ estándar en un solo lugar, pero inicialmente no saber algo acerca de la estructura específica de cualquier proyecto arbitrario, que carece de una convención local bien documentada, por lo que esperamos que el código en esos proyectos sea explícito con respecto a los bits no estándar que son únicos e implícitos con respecto a los bits estándar.

Es una buena práctica usar siempre la forma <header> de incluir para todos los encabezados estándar y otras bibliotecas que no son específicas del proyecto y usar la forma "header" para todo lo demás. ¿Debería tener un directorio de inclusión en su proyecto para su inclusión local? Eso depende en cierta medida de si esos encabezados se enviarán como interfaces a sus bibliotecas o simplemente serán consumidos por su código, y también de sus preferencias. ¿Qué tan grande y complejo es tu proyecto? Si tiene una combinación de interfaces internas y externas o muchos componentes diferentes, es posible que desee agrupar las cosas en directorios separados.

Tenga en cuenta que la estructura de directorios en la que se desempaqueta su producto terminado no tiene que parecerse en nada a la estructura de directorios en la que desarrolla y construye ese producto. Si tiene solo unos pocos archivos y encabezados .c / .cpp, puede colocar todos ellos en un directorio, pero eventualmente, trabajará en algo no trivial y tendrá que pensar en las consecuencias de sus opciones de entorno de construcción y, con suerte, documentarlo para que otros lo entiendan.