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

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top