Question

Dans un projet, j'interfère entre C++ et une bibliothèque C qui utilise stdbool.h défini comme tel.

#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

Certaines structures ont bool membres.Donc, si j'ai une de ces structures définie comme variables locales dans une fonction C++ et que je la transmets à une fonction C, les tailles sont incohérentes entre C++ et C car bool est un bye en C++ et 4 en C.

Quelqu'un a-t-il des conseils pour surmonter ce problème sans recourir à ma solution actuelle, qui est

//#define bool _Bool
#define bool unsigned char

Ce qui est contraire à la norme C99 pour stdbool.h

Était-ce utile?

La solution

J'ai trouvé la réponse à ma propre question en trouvant une implémentation plus compatible de stdbool.h conforme à la norme 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

Ceci est tiré du Bibliothèque de classe Ada projet.

Autres conseils

La taille n’est pas la seule chose qui sera incohérente ici.En C++, bool est un mot-clé, et C++ garantit qu'un bool peut contenir une valeur de 1 ou 0 et rien d'autre.C ne vous donne pas cette garantie.

Cela dit, si l'interopérabilité entre C et C++ est importante, vous pouvez émuler le booléen personnalisé de C en définissant un booléen identique pour C++ et en l'utilisant à la place du booléen intégré.Ce sera un compromis entre un booléen bogué et un comportement identique entre le booléen C et le booléen C++.

Logiquement, vous ne pouvez pas partager du code source entre C et C++ avec des déclarations contradictoires pour bool et les lier les uns aux autres.

La seule façon de partager du code et des liens est via une structure de données intermédiaire.Malheureusement, d'après ce que j'ai compris, vous ne pouvez pas modifier le code qui définit l'interface entre votre programme C++ et la bibliothèque C.Si vous le pouvez, je vous suggère d'utiliser quelque chose comme :

union boolean {
   bool value_cpp;
   int  value_c;
}; 

// un remplissage peut être nécessaire en fonction de endianité

Ce qui aura pour effet de donner au type de données la même largeur dans les deux langues ;la conversion vers le type de données natif devra être effectuée aux deux extrémités.Remplacez l'utilisation de bool par boolean dans la définition de la fonction de la bibliothèque, manipulez le code dans la bibliothèque à convertir, et vous avez terminé.

Donc, ce que vous allez devoir faire à la place, c'est créer un cale entre le programme C++ et la bibliothèque C.

Tu as:

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

Et vous devez créer :

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);
}

Et maintenant, appelez plutôt library_func_1_cpp.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top