c - gSoap generated client-side structure initialization and use -


gsoap generated client-side structure initialization , use (using ansi c bindings)

first of all, searched , although there number of struct initialization solutions offered, did not find directly answering issue.

also, question being posted assist else has similar question, i have worked out solution , because of newbie status post immediatelyat least 8 hours after posting this.

however, still interested in comments , edits solution offer better solutions, or more experience in gsoap...

the scenario:
new soap in general, , have been using gsoap generated client source code build ansi c bindings access web services. arguments 4 & 5 of "soap_call__" functions provided application interfaces (defined within soapclient.c) many times complex (nested) structures. argument 4 specifically, because it input structure, has declared, initialized, allocated , freed within calling application.

for example, given following gsoap generated prototype:

soap_fmac5 int soap_fmac6 soap_call___ns1__sendfile((struct soap *soap, const char *soap_endpoint, const char *soap_action, struct ns3__send *mtdf, struct recv *response) 

with following structure definition (looking @ argument 4) defined in soapstub.h

(note: have shortened names , reduced number of members original contents of structures illustrative purposes)

struct ns3__send {     char *wsstdate; /* optional element of type xsd:date */     int *wsstduration;  /* optional element of type xsd:int */     int *wsstfailures;  /* optional element of type xsd:int */     char *wsstfilename; /* optional element of type xsd:string */            struct ns3__param *details; /* optional element of type ns3:param */ };  struct ns3__param {     int __sizerow;  /* sequence of elements <wsstddetailsrow> */     struct ns3__row *row;   /* optional element of type ns3:xxmtdfws_wsstddetailsrow */ };  struct ns3__row {     int *wsstdseq;  /* optional element of type xsd:int */     char *wsstdstep;    /* optional element of type xsd:string */     char *wsstdtestdesc;    /* optional element of type xsd:string */     char *wsstdlowlim;  /* optional element of type xsd:string */ }; 

the question is:

how members , pointers within complex (nested) input structure initialized, memory allocated, values assigned , memory freed such useable within calling application?

originally posted address structures generated gsoap utilities specifically, has general applicability nested struct pointers...

addresses question of initializing, allocating, assigning , freeing members , pointers within nested structure construct ansi c.

to explain shape of structs requiring treatment, data schema comprised of known number of header fields, each having 1 value per row followed delimiter ********, followed unknown number of data fields, each having known (and constant) number of comma delimited fields:

example data:
enter image description here

the 2 files shown below commented. together, compile , build ansi c compiler:

initcomplexstructs.h:

    //the struct names typical in gsoap generated code     //are longer , more complicated.        //for example, typical client soap_call___ns...()     //function prototype may this:     //soap_fmac5 int soap_fmac6 soap_call___ns1__sendledf(struct soap *soap, const char *soap_endpoint, const char *soap_action, struct _ns3__ledf_send *ns3__xxmtsvclws, struct _ns3__ledf_recv *ns3__xxmtsvclwsresponse)     //where areguments 4 & 5 respectively:     // arg 4: struct _ns3__ledf_send *ns3__xxmtsvclws     // arg 5: struct _ns3__ledf_recv *ns3__xxmtsvclwsresponse     //     //for project assume arg 4 represents complex (nested)     //set of data structures, , illustration purposes, shorten     //name aaa:      // struct aaa contains members accomodate fixed number of strings     // pointer struct bbb     struct aaa  {         char *aaastr1;         char *aaastr2;         char *aaastr3;         char *aaastr4;         char *aaastr5;         struct bbb *pbbb;     };      // struct bbb used set array order size     // (or number of copies necessary of struct ccc)     // contains array size (index value) member "numrows"     // , pointer struct, work pointer     // array of struct ccc     struct bbb  {            int numrows;         struct ccc *row;     };      // struct ccc contains members accomodate variable number of      // sets of strings, number of sets determined array row[]      // initialized array size "numrows" in struct bbb     // (see initcomplexstructs.c how done)     struct ccc  {         char *cccstr1;         char *cccstr2;         char *cccstr3;         char *cccstr4;         char *cccstr5;     }; 

initcomplexstructs.c

    ///////////////////////////////////////////////////////////     ///// using nested data structures ////////////////////////     ///////////////////////////////////////////////////////////     //     //  client-side gsoap generated code use nested       //  data structures accomodate complex data types      //  used in 4th , 5th arguments of client     //  soap_call__ns...() functions.       //     //  program illustrates how work these     //  structures calling application in      //  following way :     //     //    - initialization of structs     //    - allocation of structs , members     //    - assignment of values members     //    - freeing of allocated memory     //     ///////////////////////////////////////////////////////////     ///////////////////////////////////////////////////////////      #include <ansi_c.h>     #include "initcomplexstructs.h"      struct aaa _aaa, *p_aaa;     struct bbb _bbb, *p_bbb;     struct ccc _row, *p_row;      void initializestructs(void);     void allocatestructs(void);     void assignstructs(void);     void freestructs(void);      char typicalstr[]={"aaastr 1"};     size_t sizestr = sizeof(typicalstr);      void main (void)     {         initializestructs();         allocatestructs();         assignstructs();         freestructs();     }      void initializestructs(void)     {         p_aaa = &_aaa;           p_bbb = &_bbb;           p_row = &_row;     }     void allocatestructs(void)     {         int i;         //allocate members of p_aaa          p_aaa->aaastr1 = calloc(sizestr, sizeof(char));         p_aaa->aaastr2 = calloc(sizestr, sizeof(char));         p_aaa->aaastr3 = calloc(sizestr, sizeof(char));         p_aaa->aaastr4 = calloc(sizestr, sizeof(char));         p_aaa->aaastr5 = calloc(sizestr, sizeof(char));         p_aaa->pbbb    = malloc(    sizeof(*p_bbb));          //allocate member of next nested struct - pbbb         //note:  order of array determined         //by value assigned "numrows"           //note also: value numrows passed in argument           //since calling function has information.         //just requires prototype mod void int argument.         p_aaa->pbbb->numrows = 3;         p_aaa->pbbb->row = calloc(p_aaa->pbbb->numrows,sizeof(*p_row));          //allocate innermost struct ccc accessed through *row         for(i=0;i<p_aaa->pbbb->numrows;i++)         {             p_aaa->pbbb->row[i].cccstr1 = calloc(sizestr, sizeof(char));             p_aaa->pbbb->row[i].cccstr2 = calloc(sizestr, sizeof(char));             p_aaa->pbbb->row[i].cccstr3 = calloc(sizestr, sizeof(char));             p_aaa->pbbb->row[i].cccstr4 = calloc(sizestr, sizeof(char));             p_aaa->pbbb->row[i].cccstr5 = calloc(sizestr, sizeof(char));         }     }      void assignstructs(void)     {         int i;         strcpy(p_aaa->aaastr1, "aaastr 1");          strcpy(p_aaa->aaastr1, "aaastr 2");          strcpy(p_aaa->aaastr1, "aaastr 3");          strcpy(p_aaa->aaastr1, "aaastr 4");          strcpy(p_aaa->aaastr1, "aaastr 5");          for(i=0;i<p_aaa->pbbb->numrows;i++)         {             strcpy(p_aaa->pbbb->row[i].cccstr1, "bbbstr 1");             strcpy(p_aaa->pbbb->row[i].cccstr2, "bbbstr 2");             strcpy(p_aaa->pbbb->row[i].cccstr3, "bbbstr 3");             strcpy(p_aaa->pbbb->row[i].cccstr4, "bbbstr 4");             strcpy(p_aaa->pbbb->row[i].cccstr5, "bbbstr 5");         }     }      void freestructs(void)     {         int i;         for(i=0;i<p_aaa->pbbb->numrows;i++)         {             free(p_aaa->pbbb->row[i].cccstr1);             free(p_aaa->pbbb->row[i].cccstr2);             free(p_aaa->pbbb->row[i].cccstr3);             free(p_aaa->pbbb->row[i].cccstr4);             free(p_aaa->pbbb->row[i].cccstr5);         }         free(p_aaa->pbbb->row);         free(p_aaa->pbbb);          free(p_aaa->aaastr1);         free(p_aaa->aaastr2);         free(p_aaa->aaastr3);         free(p_aaa->aaastr4);         free(p_aaa->aaastr5);     } 

Comments

Popular posts from this blog

objective c - Change font of selected text in UITextView -

php - Accessing POST data in Facebook cavas app -

c# - Getting control value when switching a view as part of a multiview -