如何避免C-header覆盖本机C ++类型

时间:2013-08-20 15:13:25

标签: c visual-c++ header boolean c-preprocessor

首先我要解释一下......

情况

  • 我有这个微控制器代码(简单的 C ),其中包含 bool.h 以及 stdbool.h 以下内容显然不可用,尤其是Visual Studio 2008,这是我目前用于VC ++和C#的IDE(见下文):

    #ifndef CUSTOM_BOOL
    #define CUSTOM_BOOL
    
    #ifdef __cplusplus
    extern "C" {
    #endif // #ifdef __cplusplus
    
    #ifndef bool
    #define bool unsigned char
    #endif
    
    #ifndef true
    #define true 1
    #endif
    
    #ifndef false
    #define false 0
    #endif
    
    #ifdef __cplusplus
    }
    #endif // #ifdef __cplusplus
    
    #endif // #ifndef CUSTOM_BOOL
    
  • 现在我需要 C#Project 微控制器代码的功能。这就是为什么我创建了一个包含托管类的中间 Visual C ++项目,它包含给定的微控制器代码。

  • 由于这个包装器项目(VC ++)摆弄了C代码,它也必须#include "bool.h"(但是间接地,这意味着包含另一个头,其本身包括bool.h - 但我认为这是一个不重要的细节)。现在这里是我的......

问题

由于 bool.h 包含在VC ++项目中,因此该项目将提供返回" real" bool(" real"这里表示使用VC ++项目时被C#识别为bool的类型),遗憾的是VC ++代码中的bool也被预处理器捕获,因此被替换为unsigned char。现在发生的事情是,C#最终抱怨不允许从unsigned char转换为bool。这一切都没关系,我理解为什么会这样。所以我的......

问题

如何在" clean"中解决此问题?办法。我目前的解决方案是,在包含bool.h之后,在VC ++代码开始之前,我再次定义了bool和朋友:

#ifdef bool
#undef bool
#endif

#ifdef true
#undef true
#endif

#ifdef false
#undef false
#endif

它有效,但它破坏了我正确的编程方式。有没有正确的方法来解决这个问题?或者问题可能发生在之前?我应该改为定义类似BOOL而不是bool的内容吗?根据我对interwebz的搜索,没有一般的"标准"在 C 项目(不支持C99)中定义bool(或BOOL?)的方法,每个人都会同意。

3 个答案:

答案 0 :(得分:1)

所以听起来微控制器项目只是组成了一种新的数据类型并称之为bool,现在bool是一个关键字(以及true和false),这恰好发生冲突?我的建议(按照优先顺序)是:

解决方案1:修复微控制器项目。 进行全局搜索并替换bool并将其替换为不那么有争议的东西。可能是C_Boolean,C_True和C_False。不太可能导致任何未来的冲突,并且使用正则表达式相当简单。

解决方案2:将微控制器项目转换为C ++。 这允许直接使用bool,true和false(作为关键字),你可以消除宏。如果微控制器代码使用不兼容c ++的语法,这可能会很困难。

解决方案3:做你已经完成的事情。 创建一个包装器包含,在包含您的微控制器代码后进行清理。我有代码依赖于重新定义extern关键字,这最终成为我唯一安全的方式。它虽然很脆弱......但是当一些不相关的东西破坏了包含结构时,你将来可能不得不修复它。

另外,我不确定原作者认为extern“C”包装器正在做什么,但它们对定义的宏没有影响。也许你删除了一些它会产生影响的东西,但宏不受链接器名称约定的影响。

答案 1 :(得分:0)

您可以使用运算符将​​返回值(char)转换为布尔值。例如,在这种情况下,您可以通过这种方式简单地比较返回值:

bool b = 0!= functionthatreturnsaboolean();

请注意,我没有使用1,因为布尔值的通常定义为0表示false,否则为其他任何内容。

另一种解决方案是简单地使用其他类型的返回值。整数应该可以正常工作。

编辑:根据评论 - 你也可以简单地创建一个调用这些函数并返回C#布尔值的接口。

bool interfacefunction()
{
  return function() != 0;
}

答案 2 :(得分:0)

感谢Keith Thompson(问题评论)和Speed8ump的回答,我得到了另一个想法:

bool.h:

#ifndef CUSTOM_BOOL
#define CUSTOM_BOOL

#ifndef __cplusplus

#ifndef bool
#define bool unsigned char
#endif

#ifndef true
#define true 1
#endif

#ifndef false
#define false 0
#endif

#endif // #ifndef __cplusplus
#endif // #ifndef CUSTOM_BOOL

像魅力一样工作,我认为它比以前的未定义的东西更清晰。但是,请随时发表评论或提供更多/更好的答案。