2008-08-24 3 views
13

Dans un projet, j'interface entre C++ et une bibliothèque C qui utilise stdbool.h défini comme tel.interfaçage avec stdbool.h C++

#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éfinies comme variables locales dans une fonction C++ et que je la passe à une fonction C, les tailles sont incohérentes entre C++ et C car bool est un au revoir en C++ et 4 en C.

des conseils sur la façon de surmonter ce sans avoir recours à ma solution actuelle qui est

//#define bool _Bool 
#define bool unsigned char 

ce qui est à la norme C99 pour stdbool.h

Répondre

10

J'ai trouvé la réponse à ma propre question en trouvant une implémentation plus compatible de stdbool.h qui est 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 provient du projet Ada Class Library.

+0

Mise à jour: _Bool est maintenant défini dans VS2013, nous devons également vérifier _MSC_VER <1800. http://msdn.microsoft.com/en-us/library/hh409293.aspx – Tom

1

Taille n'est pas la seule chose qui sera incompatible 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 en définissant un 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++.

0

Logiquement, vous n'êtes pas en mesure de partager le code source entre C et C++ avec des déclarations conflictuelles pour bool et de les lier les uns aux autres. La seule façon de partager le code et le lien est via une infrastructure de données intermédiaire. Malheureusement, d'après ce que je comprends, vous ne pouvez pas modifier le code qui définit l'interface entre votre programme C++ et la bibliothèque C. Si vous pouviez, je suggère d'utiliser quelque chose comme:

union boolean { 
    bool value_cpp; 
    int value_c; 
}; 

// rembourrage peut être nécessaire en fonction endianness

dont l'effet sera de faire le type de données de la même largeur dans les deux langues; la conversion au type de données natif devra être effectuée aux deux extrémités. Échangez l'utilisation de bool pour boolean dans la définition de fonction de bibliothèque, code de violon dans la bibliothèque pour convertir, et vous avez terminé. Donc, ce que vous allez devoir faire est de créer un shim entre le programme C++ et la bibliothèque C.

Vous avez:

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 appeler library_func_1_cpp à la place.