c++ 仅编译与主文件中使用的方法相关的方法,以释放RAM和闪存

w9apscun  于 2022-12-24  发布在  其他
关注(0)|答案(1)|浏览(91)

我正在开发一个从电子计数器读取串行数据的库。根据您的合同,计数器可以传输多达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的闪存)。
有没有办法只编译用户需要的所有东西,而不编译其余的?

mwngjboj

mwngjboj1#

我认为问题在于,您首先使用#include表示库,然后使用#define表示标记规范。
在定义所需的标记之前,编译器会“处理”库代码,因此没有一个#ifdef语句是正确的。
尝试在包含库之前定义标记。

相关问题