我正在开发一个从电子计数器读取串行数据的库。根据您的合同,计数器可以传输多达105个不同的标签。因为这个库可能是轻量级的,不强大的嵌入式系统(通常是Arduino或esp8266),我想知道是否有可能有一些东西可以让用户只要求***他感兴趣的标签,这样库就不会编译不必要的变量declaration和getter。
声明一下,我是C++和C的新手,但不是编程界的新手。我使用PlatformIO工具“Build”构建我的代码。
到目前为止,我已经为每105个标签做好了方法和变量声明,每个标签都是在一个单独的文件中的一个大的switch case语句中解码的。
file.cpp
#include "LinkyTIC.cpp"
constexpr unsigned int hash(const char* str, int h = 0){
return !str[h] ? 5381 : (hash(str, h+1) * 33) ^ str[h];
}
void substring(char* str, const char* _buffer_value, const int length){
for(int i = 0; i < length; i++){
str[i] = _buffer_value[i];
}
}
switch (hash(tag_name)){
#ifdef ADCO
case hash("ADCO"):{
substring(_ADCO, buffer_value, 12);
break;
}
#endif
#ifdef OPTARIF
case hash("OPTARIF"):{
substring(_OPTARIF, buffer_value, 4);
break;
}
#endif
#ifdef ISOUSC
case hash("ISOUSC"):{
char _tmp[2];
substring(_tmp, buffer_value, 2);
_ISOUSC = atoi(_tmp);
break;
}
#endif
#ifdef BASE
case hash("BASE"):{
char _tmp[9];
substring(_tmp, buffer_value, 9);
_BASE = atol(_tmp);
break;
}
#endif
//...
file.h
public:
#ifdef ADCO
char* GetADCO(){return _ADCO;};
#endif
#ifdef OPTARIF
char* GetOPTARIF(){return _OPTARIF;};
#endif
#ifdef ISOUSC
uint8_t GetISOUSC(){return _ISOUSC;};
#endif
#ifdef BASE
uint32_t GetBASE(){return _BASE;};
#endif
//...
private:
#ifdef ADCO
char _ADCO[12];
#endif
#ifdef OPTARIF
char _OPTARIF[4];
#endif
#ifdef ISOUSC
uint8_t _ISOUSC;
#endif
#ifdef BASE
uint32_t _BASE;
#endif
//...
在用户端,库的用途如下:
#include <Arduino.h>
#include "LinkyTIC.h"
#include <SoftwareSerial.h>
SoftwareSerial LinkySerial(13, 15);
LinkyTIC linky(LinkySerial);
#define ADCO
#define BASE
void setup() {
}
void loop() {
if(linky.read()){
linky.GetHCHP();
linky.GetOPTARIF();
linky.GetBASE();
}
}
我尝试在每个声明、属性和开关大小写中使用#ifdef
,但是,例如,当我在main.cpp中包含#define BASE
时,它对填充的RAM和闪存没有影响。
我的第二个猜测是,编译器应该足够聪明,只编译与使用的方法相关的所有内容(如GetBASE()),但它总是编译所有内容,并填充了整整1.2kB的RAM(和6kB的闪存)。
有没有办法只编译用户需要的所有东西,而不编译其余的?
1条答案
按热度按时间mwngjboj1#
我认为问题在于,您首先使用
#include
表示库,然后使用#define
表示标记规范。在定义所需的标记之前,编译器会“处理”库代码,因此没有一个
#ifdef
语句是正确的。尝试在包含库之前定义标记。