

This example will examine a hypothetical situation in which we had a structure(which represented parameters) with two fields, and then need to add a third field to our structure. If using structs directly we'd need to rewrite every piece of code that touches the struct, by using eina value, and thus having the compiler not even know the struct, we can reduce the amount of changes needed and retain interoperability between the old and new format.

Our example will start with a function that creates descriptions of both of our structs for eina value usage. The first step is to create a struct and describe its members\+: 
\begin{DoxyCodeInclude}
\textcolor{comment}{//Compile with:}
\textcolor{comment}{//gcc eina\_value\_02.c -o eina\_value\_02 `pkg-config --cflags --libs eina`}

\textcolor{preprocessor}{#include <\hyperlink{Eina_8h}{Eina.h}>}

\textcolor{keyword}{static} \hyperlink{struct__Eina__Value__Struct__Desc}{Eina\_Value\_Struct\_Desc} *V1\_DESC = NULL;
\textcolor{keyword}{static} \hyperlink{struct__Eina__Value__Struct__Desc}{Eina\_Value\_Struct\_Desc} *V2\_DESC = NULL;

\textcolor{keywordtype}{void} value\_init(\textcolor{keywordtype}{void})
\{
   \textcolor{keyword}{typedef} \textcolor{keyword}{struct }\_My\_Struct\_V1 \{
     \textcolor{keywordtype}{int} param1;
     \textcolor{keywordtype}{char} param2;
   \} My\_Struct\_V1;


   \textcolor{keyword}{static} \hyperlink{struct__Eina__Value__Struct__Member}{Eina\_Value\_Struct\_Member} v1\_members[] = \{
     \textcolor{comment}{// no eina\_value\_type as they are not constant initializers, see below.}
     \hyperlink{group__Eina__Value__Struct__Group_ga139206ef35b0b76e87eef56a202c0ae9}{EINA\_VALUE\_STRUCT\_MEMBER}(NULL, My\_Struct\_V1, param1),
     \hyperlink{group__Eina__Value__Struct__Group_ga139206ef35b0b76e87eef56a202c0ae9}{EINA\_VALUE\_STRUCT\_MEMBER}(NULL, My\_Struct\_V1, param2)
   \};
   v1\_members[0].\hyperlink{struct__Eina__Value__Struct__Member_a615cdf08597bd18623c8c7daec7b4641}{type} = \hyperlink{group__Eina__Value__Group_ga17974fd9ab773a3efefd591ffde58f77}{EINA\_VALUE\_TYPE\_INT};
   v1\_members[1].\hyperlink{struct__Eina__Value__Struct__Member_a615cdf08597bd18623c8c7daec7b4641}{type} = \hyperlink{group__Eina__Value__Group_ga0d54e0b952b44b7ac4f2fd573f7839c0}{EINA\_VALUE\_TYPE\_CHAR};

\end{DoxyCodeInclude}
 \begin{DoxyNote}{Note}
We can't pass the types of the members to E\+I\+N\+A\+\_\+\+V\+A\+L\+U\+E\+\_\+\+S\+T\+R\+U\+C\+T\+\_\+\+M\+E\+M\+B\+E\+R macro because they are not constant initializers.
\end{DoxyNote}
So far it should be pretty easy to understand, we said {\ttfamily My\+\_\+\+Struct\+\_\+\+V1} has two members, one of type {\ttfamily int} and another of type {\ttfamily char}. We now create the description of the actual struct, again nothing overly complex, we signal which version of E\+I\+N\+A\+\_\+\+V\+A\+L\+U\+E\+\_\+\+S\+T\+R\+U\+C\+T we're using, we declare no special operations, our members and our size\+: 
\begin{DoxyCodeInclude}
   \textcolor{keyword}{static} \hyperlink{struct__Eina__Value__Struct__Desc}{Eina\_Value\_Struct\_Desc} v1\_desc = \{
     \hyperlink{group__Eina__Value__Struct__Group_gae76aada4965672ce991f1f41baf71975}{EINA\_VALUE\_STRUCT\_DESC\_VERSION},
     NULL, \textcolor{comment}{// no special operations}
     v1\_members,
     \hyperlink{group__Eina__Types__Group_ga7c1b6f81660b4e30516169e9e7d3261c}{EINA\_C\_ARRAY\_LENGTH}(v1\_members),
     \textcolor{keyword}{sizeof}(My\_Struct\_V1)
   \};
   V1\_DESC = &v1\_desc;

\end{DoxyCodeInclude}


We now repeat the process for the second version of our struct, the only difference is the addition of a third parameter of type {\ttfamily int} \+: 
\begin{DoxyCodeInclude}

   \textcolor{keyword}{typedef} \textcolor{keyword}{struct }\_My\_Struct\_V2 \{
     \textcolor{keywordtype}{int} param1;
     \textcolor{keywordtype}{char} param2;
     \textcolor{keywordtype}{int} param3;
   \} My\_Struct\_V2;
   \textcolor{keyword}{static} \hyperlink{struct__Eina__Value__Struct__Member}{Eina\_Value\_Struct\_Member} v2\_members[] = \{
     \textcolor{comment}{// no eina\_value\_type as they are not constant initializers, see below.}
     \hyperlink{group__Eina__Value__Struct__Group_ga139206ef35b0b76e87eef56a202c0ae9}{EINA\_VALUE\_STRUCT\_MEMBER}(NULL, My\_Struct\_V2, param1),
     \hyperlink{group__Eina__Value__Struct__Group_ga139206ef35b0b76e87eef56a202c0ae9}{EINA\_VALUE\_STRUCT\_MEMBER}(NULL, My\_Struct\_V2, param2),
     \hyperlink{group__Eina__Value__Struct__Group_ga139206ef35b0b76e87eef56a202c0ae9}{EINA\_VALUE\_STRUCT\_MEMBER}(NULL, My\_Struct\_V2, param3)
   \};
   v2\_members[0].\hyperlink{struct__Eina__Value__Struct__Member_a615cdf08597bd18623c8c7daec7b4641}{type} = \hyperlink{group__Eina__Value__Group_ga17974fd9ab773a3efefd591ffde58f77}{EINA\_VALUE\_TYPE\_INT};
   v2\_members[1].\hyperlink{struct__Eina__Value__Struct__Member_a615cdf08597bd18623c8c7daec7b4641}{type} = \hyperlink{group__Eina__Value__Group_ga0d54e0b952b44b7ac4f2fd573f7839c0}{EINA\_VALUE\_TYPE\_CHAR};
   v2\_members[2].\hyperlink{struct__Eina__Value__Struct__Member_a615cdf08597bd18623c8c7daec7b4641}{type} = \hyperlink{group__Eina__Value__Group_ga17974fd9ab773a3efefd591ffde58f77}{EINA\_VALUE\_TYPE\_INT};
   \textcolor{keyword}{static} \hyperlink{struct__Eina__Value__Struct__Desc}{Eina\_Value\_Struct\_Desc} v2\_desc = \{
     \hyperlink{group__Eina__Value__Struct__Group_gae76aada4965672ce991f1f41baf71975}{EINA\_VALUE\_STRUCT\_DESC\_VERSION},
     NULL, \textcolor{comment}{// no special operations}
     v2\_members,
     \hyperlink{group__Eina__Types__Group_ga7c1b6f81660b4e30516169e9e7d3261c}{EINA\_C\_ARRAY\_LENGTH}(v2\_members),
     \textcolor{keyword}{sizeof}(My\_Struct\_V2)
   \};
   V2\_DESC = &v2\_desc;
\}

\end{DoxyCodeInclude}


We'll now look at a function that sets the values of our structs. For simplicity's sake we initialize it we random values, a real world case would read these values from a file, a database or even from the network. The fundamental detail here is that this function works for both V1 and V2 structs, this is because setting a parameter that a struct that doesn't have does nothing without throwing any errors\+: 
\begin{DoxyCodeInclude}

\textcolor{keywordtype}{void} rand\_init(\hyperlink{struct__Eina__Value}{Eina\_Value} *v)
\{
   \textcolor{keywordflow}{if} (v->\hyperlink{struct__Eina__Value_a1fd07b3214c901eec252a786cca47239}{type} != \hyperlink{group__Eina__Value__Group_ga8147143699c5f5a686415090080d3f9e}{EINA\_VALUE\_TYPE\_STRUCT})
     \textcolor{keywordflow}{return};

   \hyperlink{group__Eina__Value__Struct__Group_ga476aa64a399aba776fa14f2fb065b268}{eina\_value\_struct\_set}(v, \textcolor{stringliteral}{"param1"}, rand());
   \hyperlink{group__Eina__Value__Struct__Group_ga476aa64a399aba776fa14f2fb065b268}{eina\_value\_struct\_set}(v, \textcolor{stringliteral}{"param2"}, rand() % 256);
   \hyperlink{group__Eina__Value__Struct__Group_ga476aa64a399aba776fa14f2fb065b268}{eina\_value\_struct\_set}(v, \textcolor{stringliteral}{"param3"}, rand());
\}

\end{DoxyCodeInclude}
 \begin{DoxyNote}{Note}
While using \hyperlink{group__Eina__Value__Struct__Group_ga476aa64a399aba776fa14f2fb065b268}{eina\+\_\+value\+\_\+struct\+\_\+set()} with an in-\/existing parameter causes no error, it does return \hyperlink{group__Eina__Types__Group_ga1feb115f8e9913e806e090d9bd5a7301}{E\+I\+N\+A\+\_\+\+F\+A\+L\+S\+E}, to notify it was not possible to set the value. This could be used to determine that we're handling a V1 struct and take some action based on that.
\end{DoxyNote}
The next thing is to do is see what a function that uses the values of the struct looks like. We'll again be very simplistic in our usage, we'll just print the values, but a real world case, might send these values to another process use them to open a network/database connection or anything else. Since all versions of the struct have {\ttfamily param1} and {\ttfamily param2} we'll unconditionally use them\+: 
\begin{DoxyCodeInclude}

\textcolor{keywordtype}{void} my\_struct\_use(\hyperlink{struct__Eina__Value}{Eina\_Value} *params)
\{
   \textcolor{keywordtype}{int} p1, p3;
   \textcolor{keywordtype}{char} p2;

   \hyperlink{group__Eina__Value__Struct__Group_ga07a7cc420f03a247dffe4d13ce1ad6c5}{eina\_value\_struct\_get}(params, \textcolor{stringliteral}{"param1"}, &p1);
   \hyperlink{group__Eina__Value__Struct__Group_ga07a7cc420f03a247dffe4d13ce1ad6c5}{eina\_value\_struct\_get}(params, \textcolor{stringliteral}{"param2"}, &p2);
   printf(\textcolor{stringliteral}{"param1: %d\(\backslash\)nparam2: %c\(\backslash\)n"}, p1, p2);

\end{DoxyCodeInclude}


The next step is to conditionally use {\ttfamily param3}, which can fortunately be done in the same step in which we get it's value\+: 
\begin{DoxyCodeInclude}

   \textcolor{keywordflow}{if} (\hyperlink{group__Eina__Value__Struct__Group_ga07a7cc420f03a247dffe4d13ce1ad6c5}{eina\_value\_struct\_get}(params, \textcolor{stringliteral}{"param3"}, &p3))
     printf(\textcolor{stringliteral}{"param3: %d\(\backslash\)n"}, p3);
\}

\end{DoxyCodeInclude}


There we've now got functions that can both populate and use values from both our structs, so now let's actually use them in our main function by creating a struct of each type, initializing them and them using them\+: 
\begin{DoxyCodeInclude}

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{int} argc, \textcolor{keywordtype}{char} **argv)
\{
   (void)argc;
   (void)argv;
   \hyperlink{struct__Eina__Value}{Eina\_Value} *v1, *v2;

   \hyperlink{group__Eina__Main__Group_gabf448ada5bc81a07342b66c6f818ee5e}{eina\_init}();
   value\_init();
   srand(time(NULL));

   v1 = \hyperlink{group__Eina__Value__Struct__Group_gaf469abb97ac59b73e8b2c726a58a78f8}{eina\_value\_struct\_new}(V1\_DESC);
   v2 = \hyperlink{group__Eina__Value__Struct__Group_gaf469abb97ac59b73e8b2c726a58a78f8}{eina\_value\_struct\_new}(V2\_DESC);

   rand\_init(v1);
   my\_struct\_use(v1);

   rand\_init(v2);
   my\_struct\_use(v2);

   \hyperlink{group__Eina__Value__Value__Group_gaa2aa7ac9d1fcd7c4497cf104cb374a52}{eina\_value\_free}(v1);
   \hyperlink{group__Eina__Value__Value__Group_gaa2aa7ac9d1fcd7c4497cf104cb374a52}{eina\_value\_free}(v2);
   \hyperlink{group__Eina__Main__Group_ga6741fcaba116e31e96ce14dcfa03f568}{eina\_shutdown}();
\}

\end{DoxyCodeInclude}


This concludes our example. For the full source code see \hyperlink{eina_value_02_c}{eina\+\_\+value\+\_\+02.\+c}. 