Советы и хитрости всегда существуют. Взгляните на библиотеку Metaresc https://github.com/alexanderchuranov/Metaresc
Предоставляет интерфейс для объявления типов, который также генерирует метаданные для типа. На основе метаданных вы можете легко сериализовать / десериализовать объекты любой сложности. Из коробки вы можете сериализовать / десериализовать XML, JSON, XDR, Lisp-подобные нотации, C-init нотации.
Вот простой пример:
#include <stdio.h>
#include <stdlib.h>
#include "metaresc.h"
TYPEDEF_STRUCT (host_t,
(char *, host),
int port,
);
TYPEDEF_STRUCT (config_t,
(host_t, local),
(host_t, remote),
(char *, name),
);
int main (int argc, char * argv[])
{
config_t config = {
.local = {
.host = "localhost",
.port = 8080,
},
.remote = {
.host = "google.com",
.port = 80,
},
.name = "service",
};
char * str = MR_SAVE_XML (config_t, &config);
if (str)
{
printf ("%s\n", str);
free (str);
}
return (EXIT_SUCCESS);
}
Эта программа выведет
$ ./config
<?xml version="1.0"?>
<config>
<local>
<host>localhost</host>
<port>8080</port>
</local>
<remote>
<host>google.com</host>
<port>80</port>
</remote>
<name>service</name>
</config>
Библиотека прекрасно работает для последних версий gcc и clang.