interface com stdbool.h C++
Pergunta
Em um projeto, estou fazendo interface entre C++ e uma biblioteca 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
Algumas estruturas têm bool
membros.Portanto, se eu tiver uma dessas estruturas definidas como variáveis locais dentro de uma função C++ e passá-la para uma função C, os tamanhos serão inconsistentes entre C++ e C, pois bool é um adeus em C++ e 4 em C.
Alguém tem algum conselho sobre como superar isso sem recorrer à minha solução atual, que é
//#define bool _Bool
#define bool unsigned char
O que é contra o padrão C99 para stdbool.h
Solução
Encontrei a resposta para minha própria pergunta ao encontrar uma implementação mais compatível de stdbool.h
compatível com o padrão 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
Isto é retirado do Biblioteca de classes Ada projeto.
Outras dicas
O tamanho não é a única coisa que será inconsistente aqui.Em C++, bool é uma palavra-chave e C++ garante que um bool pode conter um valor de 1 ou 0 e nada mais.C não lhe dá essa garantia.
Dito isto, se a interoperabilidade entre C e C++ for importante, você poderá emular o booleano personalizado do C definindo um booleano idêntico para C++ e usando-o em vez do bool interno.Isso será uma troca entre um booleano com erros e um comportamento idêntico entre o booleano C e o booleano C++.
Logicamente, você não é capaz de compartilhar código-fonte entre C e C++ com declarações conflitantes para bool e fazer com que eles sejam vinculados entre si.
A única maneira de compartilhar código e link é por meio de uma estrutura de dados intermediária.Infelizmente, pelo que entendi, você não pode modificar o código que define a interface entre seu programa C++ e a biblioteca C.Se você pudesse, sugiro usar algo como:
union boolean {
bool value_cpp;
int value_c;
};
// preenchimento pode ser necessário dependendo endianismo
O efeito disso será fazer com que o tipo de dados tenha a mesma largura em ambos os idiomas;a conversão para o tipo de dados nativo precisará ser realizada em ambas as extremidades.Troque o uso de bool por booleano na definição da função da biblioteca, mexa no código da biblioteca para converter e pronto.
Então, o que você terá que fazer é criar um calço entre o programa C++ e a biblioteca C.
Você tem:
extern "C" bool library_func_1(int i, char c, bool b);
E você precisa criar:
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);
}
E agora chame library_func_1_cpp.