sobre - similitudes entre java y c++
Compatibilidad de compilaciĆ³n de C vs C++: no nombra un tipo (3)
Parece que tienes un archivo de encabezado que es ilegal en C ++, por lo que no puedes
#include
en el código compilado como C ++.
Si no puede efectuar un cambio en el archivo del encabezado de la biblioteca (por ejemplo, quejándose con su proveedor de la biblioteca), la opción más sencilla es escribir un contenedor delgado compatible con C ++ alrededor de la biblioteca:
Para aislar su código C ++ contra el encabezado C, cree un
Wrapper.h
Wrapper.c
, donde
.h
es válido para su inclusión en C ++,
no
incluye
header.h
, y proporciona todos los tipos y funciones que necesita para la interacción de la biblioteca. .
Luego, en el
.c
, puede
#include "header.h"
e implementar todas las llamadas (y lo que sea necesario para convertir de forma segura entre los tipos).
Obviamente, esto tendría que compilarse como C, no como C ++.
Estoy tratando de usar la biblioteca de un proveedor en combinación con mi aplicación C ++.
La biblioteca se basa en gran medida en C, que normalmente no es un problema con la opción
extern "C"
, pero me encontré con un problema que el compilador de C ++ no acepta.
Simplifiqué mi código en los siguientes archivos de ejemplo. header.h representa un encabezado de la biblioteca de suppier, main.c / cpp son mis propios archivos. Mi aplicación real es una aplicación de C ++, por lo que quiero que funcione con main.cpp.
header.h (note la línea
u64 u64;
):
#ifndef HEADER_H
#define HEADER_H
#include <stdint.h>
typedef uint64_t u64;
union teststruct {
u64 u64;
struct {
u64 x:32;
u64 y:32;
} s;
};
#endif
C Principal:
#include <stdio.h>
#include "header.h"
int main() {
union teststruct a;
a.u64=5;
printf("%x/n", a.u64);
return 0;
}
main.cpp (igual que main.c pero con una declaración
extern "C"
adicional):
#include <stdio.h>
extern "C" {
#include "header.h"
}
int main() {
union teststruct a;
a.u64=5;
printf("%x/n", a.u64);
return 0;
}
Compilando main.c usando la línea
gcc -o test main.c
Se compila sin problemas. Sin embargo, compilando la versión de C ++ usando el compilador g ++ con el comando
g++ -o test main.cpp
da los siguientes errores de compilación:
In file included from main.cpp:12:0:
header.h:11:9: error: ‘u64’ does not name a type
u64 x:32;
^
header.h:12:9: error: ‘u64’ does not name a type
u64 y:32;
^
El problema es que el proveedor usó el mismo nombre (u64) tanto para el tipo como para el nombre de la variable, lo que parece una mala idea, pero parece que gcc lo acepta. No quiero cambiar la biblioteca (es decir, header.h) ya que es muy grande, esto ocurre mucho en el código y ocasionalmente recibo actualizaciones para él. ¿Hay una manera de hacer que g ++ acepte esta combinación, o una manera de modificar main.cpp para que se compile sin cambiar header.h?
Si su única incompatibilidad entre C y C ++ es la única, debería poder convertir
header.h
a un archivo de encabezado compatible con C ++ mediante programación,
header.hpp
nombre algo así como
header.hpp
.
Y luego puedes convertir las versiones más nuevas de la misma manera.
Los errores del compilador le dicen todo sobre qué y dónde se debe cambiar:
header.h:11:9: error: ‘u64’ does not name a type
-
Abrir
header.h
; - Busque la posición 11: 9;
-
Insertar
::
allí; -
Repetir para todos
does not name a type
error dedoes not name a type
.
Un poco de procesamiento de cadenas y se hace.
PS: Los convertidores de C a C ++ pueden hacer eso también.
teststruct
define un alcance en C ++.
Usted puede formar el id calificado
teststruct::u64
.
Por lo tanto, las reglas de idioma para la búsqueda de nombres cuentan para eso, permitiendo a los miembros de clases y uniones ocultar los identificadores en el ámbito externo.
Una vez
u64 u64;
se introduce, el
u64
no calificado no puede referirse al global
::u64
, solo el miembro.
Y el miembro no es un tipo.
En C
union teststruct
no define un alcance.
El campo solo se puede usar en el acceso de miembros, por lo que nunca puede surgir un conflicto.
Como tal, el campo no necesita ocultar el identificador de tipo de alcance de archivo.
Por lo que puedo decir, no hay nada que puedas hacer para solucionarlo fácilmente.
Esta biblioteca (que es una biblioteca de C perfectamente válida), no es una biblioteca de C ++ válida.
No es diferente si se usara
new
o
try
como nombres de variables.
Necesita ser adaptado.