Pregunta

En un proyecto, estoy interactuando entre C ++ y una biblioteca de C que usa stdbool.h definido como tal.

#ifndef _STDBOOL_H
#define _STDBOOL_H

/* C99 Boolean types for compilers without C99 support */
/* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */
#if !defined(__cplusplus)

#if !defined(__GNUC__)
/* _Bool builtin type is included in GCC */
typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
#endif

#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1

#endif

#endif

Algunas estructuras tienen miembros bool . Entonces, si tengo una de estas estructuras definidas como variables locales dentro de una función C ++ y la paso a una función C, los tamaños son inconsistentes entre C ++ y C ya que bool es un adiós en C ++ y 4 en C.

¿Alguien tiene algún consejo sobre cómo superar esto sin recurrir a mi solución actual que es

//#define bool _Bool
#define bool unsigned char

Que está en contra del estándar C99 para stdbool.h

¿Fue útil?

Solución

Encontré la respuesta a mi propia pregunta al encontrar una implementación más compatible de stdbool.h que cumple con el estándar C99.

#ifndef _STDBOOL_H
#define _STDBOOL_H

#include <stdint.h>

/* C99 Boolean types for compilers without C99 support */
/* http://www.opengroup.org/onlinepubs/009695399/basedefs/stdbool.h.html */
#if !defined(__cplusplus)

#if !defined(__GNUC__)
/* _Bool builtin type is included in GCC */
/* ISO C Standard: 5.2.5 An object declared as 
type _Bool is large enough to store 
the values 0 and 1. */
/* We choose 8 bit to match C++ */
/* It must also promote to integer */
typedef int8_t _Bool;
#endif

/* ISO C Standard: 7.16 Boolean type */
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1

#endif

#endif

Esto se ha tomado del proyecto Ada Class Library .

Otros consejos

El tamaño no es lo único que será inconsistente aquí. En C ++, bool es una palabra clave, y C ++ garantiza que un bool puede contener un valor de 1 o 0 y nada más. C no te da esta garantía.

Dicho esto, si la interoperabilidad entre C y C ++ es importante, puede emular el booleano personalizado de C definiendo uno idéntico para C ++ y usándolo en lugar del booltin booltin. Eso será una compensación entre un booleano con errores y un comportamiento idéntico entre el booleano C y el booleano C ++.

Lógicamente, no puede compartir el código fuente entre C y C ++ con declaraciones en conflicto para bool y hacer que se vinculen entre sí.

La única forma de compartir el código y el enlace es a través de una estructura de datos intermedia. Desafortunadamente, por lo que entiendo, no puede modificar el código que define la interfaz entre su programa C ++ y la biblioteca C. Si pudieras, te sugeriría usar algo como:

union boolean {
   bool value_cpp;
   int  value_c;
}; 

// puede ser necesario rellenar dependiendo de endianness

El efecto será hacer que el tipo de datos tenga el mismo ancho en ambos idiomas; la conversión al tipo de datos nativo deberá realizarse en ambos extremos. Cambie el uso de bool por boolean en la definición de la función de la biblioteca, el código de violín en la biblioteca para convertir, y listo.

Entonces, lo que vas a tener que hacer es crear una shim entre el programa C ++ y la biblioteca C

Tienes:

extern "C" bool library_func_1(int i, char c, bool b);

Y necesitas crear:

bool library_func_1_cpp(int i, char c, bool b)
{
   int result = library_func_1(i, c, static_cast<int>(b));
   return (result==true);
}

Y ahora llame a library_func_1_cpp en su lugar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top