替换C代码宏并在C ++代码中定义常量

时间:2017-12-05 16:45:16

标签: c++ c

我的问题要点:我的项目包含C和C ++文件,一些字符串常量(它们在带有#define的项目的C部分中被硬编码)是连接到计算机所必需的通过USB,但如果我连接两个或多个相同类型的设备,它们会停止响应,因为这些常量是相同的。解决这个问题的方法是从C ++文件中动态分配这些常量,这样C ++代码中的变量就可以到达C部分,这些值就是使用这些值。

我现在拥有的内容:值在C标头中定义为#define IDENTIFIER VALUE硬编码),其中VALUE均为{{1}原始常量C,如int0x1234数组,如char。例如:

"Some string"

我知道C中的方法将这些标识符与#define IDENTIFIER1 0x1234 #define IDENTIFIER2 0x5678 #define IDENTIFIER3 "Some string" #define IDENTIFIER4 "Another string" LOBYTE等其他宏一起使用,值也会传递给某些函数。

我尝试通过用HIBYTE中包含的defines变量定义替换字符串static cast char[]来解决此问题,但编译器注意到标识符在某些函数中初始化非常量变量或者是作为参数传递。

我成功编译了代码,其中我将#ifndef中的字符串更改为#define IDENTIFIER VALUE,但我仍然需要在C ++中定义它们。

但是我很难定义像static const unsigned char IDENTIFIER[] = VALUE;这样的十六进制数字。我发现其他question包含与我的问题相关的内容,到目前为止,我已尝试通过以下方式定义十六进制值(found out that uint8_t is just a typedef of unsigned char,还发现了一些questions将数字转换为0x1234和某些answers to questions about casting types):

unsigned char

有一个函数使用IDENTIFIERs作为参数,它的原型如下所示:

static uint8_t IDENTIFIER[] = {0x12, 0x34, 0};

static const uint8_t IDENTIFIER[] = {0x12, 0x34, 0};

static const uint8_t IDENTIFIER[] = (uint8_t*)0x1234;

static const uint16_t identifier_int = 0x1234;
static const unsigned char IDENTIFIER[3] = identifier_int;

以后会这样调用:

void foo (uint8_t *bar, /*other arguments*/);

我想要实现的目标:值应该在C ++代码中定义,它应该使用某种方法将这些值传递给C代码。

问题:

  1. 将值从C ++代码传递给C代码的最佳方法是什么?有什么替代品?
  2. 如果我能提高问题的清晰度,请通知我!

    非常感谢@AhmedMasud帮助我更清楚地定义我的问题并提供一些提示来澄清问题。

2 个答案:

答案 0 :(得分:1)

  

值应该在C ++代码中定义,它应该使用某种方法   将这些值传递给C代码然后定义它们。

您可以在一般意义上做到这一点,但是使其与现有C代码一起使用将需要更改该代码。这些变化可能显然是非平凡的。

  

如果我理解   正确的宏将所有使用IDENTIFIER的地方更改为VALUE   在编译之前,

是的,这是一个相当不错的特征。

  

因此我认为不应该使用宏   了。

我想你的意思是因为你想在运行时设置值,你不能使用宏。那是对的。在C代码中容纳这种最不具破坏性的方法可能是声明并使用外部变量来保存值。但请注意,为了将C代码转换为以这种方式工作,您可能需要解决各种各样的问题。

  

我希望代码看起来像

void setIdentifier(identifier)
{
#ifndef IDENTIFIER
static const unsigned char IDENTIFIER[] = identifier;
#endif
}
     

据我所知const应该已经做到了。

不,它看起来不会那样。

首先,你说合理地说,你不想使用宏。在这种情况下,#ifndef IDENTIFIER#endif无法发挥作用。

第二,你在一个函数中声明了变量IDENTIFIER,所以它没有链接。如果你想要一个函数来设置它,你需要一个外部变量,并且需要一个不同的函数来读取它。

第三,由于你需要一个外部变量,你将无法使用初始化器来设置它的值。如果将变量声明为char数组(而不是char *),则需要使用strcpy()或类似函数将参数的字符复制到该数组中。但是,您可以对数字或指针变量使用简单赋值。

  
      
  1. 我不太了解与C ++中的C代码进行交互,将C ++代码中的值传递给C代码的最佳方法是什么?什么   有替代品吗?
  2.   

与传递C ++代码中的值几乎相同的替代方法:将值存储在可访问的变量中,或将其作为函数参数传递。 C没有“方法”,但为此目的,C ++方法可以被认为是一种功能。

  
      
  1. 在分配这些“常数”时,我应该采取什么预防措施?我注意到建议使用static const代替。{   #define,如上所述,在这种情况下使用宏可能不太可能。
  2.   

这个问题没有意义。如果你有一个常量,那么就不能为它赋值(注意分配给初始化不同)。如果要在编译时设置其值,可以使用文件范围conststatic const变量,但是正在使用的宏已经完成了。为什么要改变所有的工作?

另一方面,如果要在运行时分配它们,则需要 - const变量。此外,如果要在一个源文件中分配将从另一个源文件中读取的值,则需要外部变量(非static)。

  
      
  1. C ++程序中定义的静态const是否可以在C代码中看到?
  2.   

在文件/命名空间范围内,不,因为在该上下文中防止这是static的确切目的。在函数或方法内部,不,因为函数/方法的局部变量在声明它们的函数/方法之外是不可见的。所以,没有。

如果你想要一个函数或方法可以写入的变量以及另一个函数或方法可以读取的变量,并且至少有一个访问变量的函数是用C实现的,那么你需要一个文件范围的外部变量。这样的变量是声明给所有用户(包括C和C ++)以及这种形式的文件范围声明:

/* "extern" is essential */
extern int IDENTIFIER1;

通常会将其放在头文件中,该文件中包含访问变量的所有源。此外,项目中只有一个源文件必须定义变量,并使用以下形式的代码:

/*
 * either the initializer or the absence of "extern" is essential;
 * both together is good form.
 */
int IDENTIFIER1 = 0x1234;

答案 1 :(得分:0)

我将从简单替换宏定义开始

#define IDENTIFIER1 0x1234
#define IDENTIFIER2 0x5678
#define IDENTIFIER3 "Some string"
#define IDENTIFIER4 "Another string"

const auto IDENTIFIER1 = 0x1234;
const auto IDENTIFIER2 = 0x5678;
const auto IDENTIFIER3 = "Some string";
const auto IDENTIFIER4 = "Another string";

之后,如果发生问题,我会逐步解决问题。