gSOAP的生成的客户端的结构的初始化和使用 [英] gSoap generated client-side structure initialization and use
问题描述
gSOAP的生成的客户端结构的初始化和使用(使用ANSI C绑定)
gSoap generated client-side structure initialization and use (using ANSI C bindings)
首先,我搜索,虽然有提供一些结构初始化的解决方案,我没发现什么直接回答这个问题。
First of all, I searched and although there are a number of struct initialization solutions offered, I did not find anything directly answering this issue.
此外,这个问题被简单地张贴到帮助别人,有一个类似的问题,因为的我已经制定了解决方案,并因为我的新手状态
将它张贴立即 至少8小时
发布之后。的
Also, this question is being posted simply to assist anyone else that has a similar question, as I have already worked out the solution and because of my newbie status
will post it immediatelyat least 8 hours
after posting this.
不过,我仍然在评论和编辑的解决方案,我会从那些具有更好的解决方案提供了非常有兴趣,或在gSOAP的...
However, I am still very interested in comments and edits to the solution I will offer from those with better solutions, or with more experience in gSoap...
的情景:的结果
我是相当新的肥皂一般,而一直在使用gSOAP的生成客户端源$ C $ C建立ANSI C绑定来访问Web服务。参数4和作为应用程序接口(内soapClient.c定义)提供的soap_call__功能,5是多次复杂的(嵌套)结构。说法4具体地说,是因为它是输入结构,都将被声明,初始化,分配和调用应用程序中解脱出来。
The Scenario:
I am fairly new to soap in general, and have been using gSoap generated client source code to build ANSI C bindings to access web services. Arguments 4 & 5 of the "soap_call__" functions provided as application interfaces (defined within soapClient.c) are many times complex (nested) structures. Argument 4 specifically, because it it is the input structure, has to be declared, initialized, allocated and freed within the calling application.
例如,下面给出gSOAP的产生原型:
for example, given the 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)
在soapStub.h定义的结构如下定义(仅在参数4看)
with the following structure definition (looking only at argument 4) defined in soapStub.h
(注意:我已经缩短的名称和用于说明目的的结构,原来的内容减少成员数量)的
(NOTE: I have shortened the names and reduced the number of members from original contents of the structures for 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 are the members and pointers within this complex (nested) input structure properly initialized, memory allocated, values assigned and memory freed such that they are useable within a calling application?
推荐答案
最初发布以解决具体gSOAP的实用工具产生的结构,但它具有普遍的适用性与指针的嵌套结构...
地址初始化,分配,分配和释放的嵌套结构中的成员和指针构建ANSI C的问题。
Addresses question of initializing, allocating, assigning and freeing members and pointers within a nested structure construct for ANSI C.
要解释需要这种治疗结构的形状,该数据模式是由一个 已知的报头字段的号码,然后由分隔符每行每一个都具有价值 **** ,随后由 未知的数据字段的数量,每个具有已知(常量)数量以逗号分隔的字段:
To explain the shape of structs requiring this treatment, The data schema is comprised of a known number of header fields, each having one value per row followed by a delimiter ****, that followed by an unknown number of data fields, each having a known (and constant) number of comma delimited fields:
示例数据:的结果
Example data:
下面所示的两个文件完全注释。同时,他们将编译与任何ANSI C编译器编译:
The two files shown below are fully commented. Together, they will compile and build with any ANSI C compiler:
InitComplexStructs.h:的
InitComplexStructs.h:
//The struct names typical in gSoap generated code
//are longer and more complicated.
//for example, a typical client soap_call___ns...()
//function prototype may look like 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 are respectively:
// arg 4: struct _ns3__ledf_send *ns3__xxmtsvclws
// arg 5: struct _ns3__ledf_recv *ns3__xxmtsvclwsResponse
//
//for this project we will assume arg 4 represents a complex (nested)
//set of data structures, and for illustration purposes, shorten the
//name to aaa:
// struct aaa contains members to accomodate a fixed number of strings
// as well as a pointer to struct bbb
struct aaa {
char *aaaStr1;
char *aaaStr2;
char *aaaStr3;
char *aaaStr4;
char *aaaStr5;
struct bbb *pBbb;
};
// struct bbb is used to set array order size
// (or the number of copies necessary of struct ccc)
// it contains the array size (index value) member "numRows"
// and a pointer to a struct, which will work like a pointer
// to array of struct ccc
struct bbb {
int numRows;
struct ccc *row;
};
// struct ccc contains members to accomodate a variable number of
// sets of strings, number of sets determined by the array row[]
// initialized to array size "numRows" in struct bbb
// (see initComplexStructs.c for how this is done)
struct ccc {
char *cccStr1;
char *cccStr2;
char *cccStr3;
char *cccStr4;
char *cccStr5;
};
InitComplexStructs.c 的
InitComplexStructs.c
///////////////////////////////////////////////////////////
///// Using nested data structures ////////////////////////
///////////////////////////////////////////////////////////
//
// client-side gSoap generated code will often use nested
// data structures to accomodate complex data types
// used in the 4th and 5th arguments of the client
// soap_call__ns...() functions.
//
// This program illustrates how to work with these
// structures by a calling application in the
// following way :
//
// - Initialization of structs
// - Allocation of structs and members
// - Assignment of values to 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: The order of array is determined
//by the value assigned to "numRows"
//Note also: the value for numRows could be passed in by argument
//since the calling function has this information.
//Just requires prototype mod from void to int argument.
p_aaa->pBbb->numRows = 3;
p_aaa->pBbb->row = calloc(p_aaa->pBbb->numRows,sizeof(*p_row));
//Allocate the 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);
}
这篇关于gSOAP的生成的客户端的结构的初始化和使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!