In the past, I have used a macro for initializing an Struct with this scheme:
node.h
typedef struct Node_TypeDef
{
uint16_t netId;
const uint8_t UID[6];
}Node_TypeDef
#define NODE_INIT \
{ \
0x0002, /*NetID*/ \
{0x03, 0x44, 0x03, 0x00, 0xA0, 0x08}, /*UID*/ \
}
main.c
#include "node.h"
int main(void) {
Node_TypeDef node = NODE_INIT;
/*More Code*/
}
Now I want to put the initialization code in a function that receives a pointer to the struct, then populates it depending on the second parameter using the macro directives. Something like this:
node.h
typedef struct Node_TypeDef
{
uint16_t netId;
const uint8_t UID[6];
}Node_TypeDef
#define NODE_INIT_1 \
{ \
0x0001, /*NetID*/ \
{0x03, 0x44, 0x03, 0x00, 0xA0, 0x08} /*UID*/ \
}
#define NODE_INIT_2 \
{ \
0x0001, /*NetID*/ \
{0x03, 0x44, 0x03, 0x00, 0xA0, 0x08} /*UID*/ \
}
.
.
.
.
#define NODE_INIT_N \
{ \
0x0001, /*NetID*/ \
{0x03, 0x75, 0x03, 0x00, 0xD0, 0x0A} /*UID*/ \
}
void initNode (Node_TypeDef *node, uint8_t mode);
node.c
#include node.h
Node_TypeDef ptrNode;
void initNode (Node_TypeDef *node, uint8_t mode)
{
switch (mode) {
case 1:
*node = NODE_INIT_1;
break;
case 2:
*node = NODE_INIT_2;
break;
.
.
.
default:
break;
}
ptrNode = node;
}
main.c
#include "node.h"
int main(void) {
Node_TypeDef node;
initNode (&node,2);
/*More Code*/
}
Nevertheless, as a macro, it's not a variable. It is replaced in compilation time; the deference operator can not just assign the value. Furthermore, as is a struct, I should use a memcpy()
for assigning it, but I need the memory address where this constant was placed.
In Summary:
How can I assign a value to my struct that was passed by reference to a constant value defined in a macro?
I appreciate any help with this.
CodePudding user response:
For this, you need compound literal:
#define NODE_INIT \
((struct Node_TypeDef){ \
0x0002, /*NetID*/ \
{0x03, 0x44, 0x03, 0x00, 0xA0, 0x08}, /*UID*/ })
After that, this should work:
*node = NODE_INIT;
CodePudding user response:
Only the (type) information was missing. Kudos to @hyde for the link: compound literal
#include <stdint.h>
#include <stdio.h>
typedef struct Node_TypeDef
{
uint16_t netId;
uint8_t UID[6];
} Node_TypeDef;
#define NODE_INIT_1 (Node_TypeDef) \
{ \
0x0001, /*NetID*/ \
{0x03, 0x44, 0x03, 0x00, 0xA0, 0x08} /*UID*/ \
}
void initNode (Node_TypeDef *node, uint8_t mode);
Node_TypeDef *ptrNode;
void initNode (Node_TypeDef *node, uint8_t mode)
{
switch (mode) {
case 1:
*node = NODE_INIT_1;
break;
default:
break;
}
ptrNode = node;
}
int main(void) {
Node_TypeDef node;
initNode (&node,1);
printf("netId: %d\n", node.netId);
/*More Code*/
return 0;
}
netId: 1
Test at online environment