Witam!
W pewnych momentach C jest dość irytujące, w szczególności że na niektóre platformy jest taki kompilator i koniec.
Postanowiłem stworzyć pewne nakładki, najpierw zabrałem się za nowy typ w C.
Nowy typ jest szablonem, który dodatkowo zawiera informacje o wielkości, nazwie, typie.
#include <stdio.h>
#include <string.h>
// szablon nowego typu
typedef struct{
size_t size;
char * name;
char * type;
unsigned char data[];
} var_template;
// funkcja ktora prezentuje jak mozna wykorzystac nowy typ
void var_dump(void *ptr){
int i;
var_template * t = (var_template*) ptr;
printf("%s\n", __FUNCTION__);
printf(" name: %s\n", t->name);
printf(" type: %s\n", t->type);
printf(" size: %lu\n", t->size);
printf(" dump: ");
for(i=0; i<(int)t->size; ++i){
printf("%02x ", t->data[i]);
}
printf("\n");
}
// tworzenie nowego typu
#define TO_STR2(x) #x
#define TO_STR(x) TO_STR2(x)
#define var(TYPE, NAME) \
struct{ \
size_t size; \
char * name; \
char * type; \
typeof(TYPE) data; \
} NAME = { \
.size = sizeof(TYPE), \
.name = TO_STR(NAME), \
.type = TO_STR(TYPE), \
};
// missing initializer for member ... data
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
//#define var_data(TYPE, PTR) (TYPE)(((var_template*)PTR)->data)
#define var_data(TYPE, PTR) ({ \
const var_template* t = (var_template*) PTR; \
strcmp(t->type, TO_STR(TYPE)) == 0 ? (TYPE*) t->data : 0; \
})
struct my_struct{
char a;
char b;
};
// przyklad 2
void my_struct_print(void * ptr){
struct my_struct * s = var_data(struct my_struct, ptr);
if(s)
printf("%s: %d, %d\n", __FUNCTION__, s->a, s->b);
else
printf("%s: error\n", __FUNCTION__);
}
int main(){
// przyklad nakladki na int
printf("\nNakladka na int\n");
var(int, foo);
foo.data = 0x12345678;
var_dump(&foo);
my_struct_print(&foo);
// przyklad nakladki na strukture
printf("\nNakladka na struct my_struct\n");
var(struct my_struct, s);
s.data.a = 1;
s.data.b = 2;
var_dump(&s);
my_struct_print(&s);
return 0;
}
Wynik:
Nakladka na int
var_dump
name: foo
type: int
size: 4
dump: 78 56 34 12
my_struct_print: error
Nakladka na struct my_struct
var_dump
name: s
type: struct my_struct
size: 2
dump: 01 02
my_struct_print: 1, 2
Pytania:
- Czy uda się zmanipulować tak "#define" by deklarowanie zmiennych wyglądało tak:
var(int) foo;
??
Bardzo przeszkadza sposób deklaracji struktury razem z danymi:
struct{
int a;
} name = {
.a = 12,
};
Gdyby nazwa była na końcu, nie byłoby problemu.
-
missing initializer for member ... data
W nie mogę nic wpisać, ponieważ są to różne typy, ale kompilator swoje.
Da się jakoś ominąć ten warning?
Jakiś sposób, aby jednak coś wpisać?
Może jakoś wyłączyć warninga przy tworzeniu struktury i później włączyć z powrotem? -
Jakieś dodatkowe pomysły, sugestie?
Czeka mnie jeszcze dużo pracy i mile wiedziane podpowiedzi ;)