J'écris des bibliothèques pour un microcontrôleur, et à cette fin, j'utilise des fonctions de type macro. Par exemple, une fonction de macro-like pour permettre à un module de I2C est défini comme:Concaténation des constantes macro en utilisant ##
#define I2C_MODULE_ENABLE(_x) \
I2C##_x##CONLbits.I2CEN = 1
où _x
est le nombre de modules (par exemple, 1
ou 2
dans mon cas).
Si un utilisateur appelle cette fonction de type macro comme I2C_MODULE_ENABLE(1)
, il sera développé par un préprocesseur sous la forme I2C1CONLbits. I2CEN = 1
.
Cependant, si un utilisateur appelle cette fonction macro semblable comme I2C_MODULE_ENABLE(MY_I2C)
, où MY_I2C
est une constante macro définie dans un fichier config.h
défini par l'utilisateur qui est inclus par ma bibliothèque i2c.h
(par exemple, la constante macro est définie comme #define MY_I2C 1
) , la fonction de type macro serait étendue en tant que I2CMY_I2CCONLbits. I2CEN = 1
.
Je sais que je dois évaluer en quelque sorte la MY_I2C
constante macro avant concaténation, et je peux le faire en ajoutant un autre niveau macro:
#define __I2CxCONLbits(_x) I2C##_x##CONLbits
#define I2C_MODULE_ENABLE(_x) \
__I2CxCONLbits.I2CEN = 1
Ma question est: est-il une solution plus élégante à ce problème puisque j'ai plusieurs registres comme le registre CONLbits
. En utilisant cette approche, je devrais définir une macro spéciale __I2CxREGISTER(_x)
pour chaque registre.
J'ai essayé de faire quelque chose comme ceci:
#define __I2Cx(_x) I2C##_x
#define I2C_MODULE_ENABLE(_x) \
__I2Cx(_x)##CONLbits.I2CEN = 1
mais qui produit une sortie comme ceci: I2C1 CONLbits .I2CEN = 1
, et mon compilateur se plaint l'espace entre les I2C1
et CONLbits
jetons.
Cela ne résout pas vraiment le problème/réponds à la question. – melpomene
@melpomene - J'y suis finalement arrivé. J'ai eu du mal à vérifier l'exemple de code sur mon compilateur de nuage préféré :) – StoryTeller
Cela est toujours codé en dur pour utiliser 'CONLbits'. – melpomene