struct soap
信息源 Genivia - soap Struct Reference
这是管理gsoap引擎状态上下文的一个类,在所有gSOAP函数中,总是作为第一个参数传入,只能在单线程中使用。每个线程应该使用独立的一个对象。
堆上创建struct soap
这种方式更常见
struct soap *soap1 = soap_new();
struct soap *soap2 = soap_new1(input_and_output_mode);
struct soap *soap3 = soap_new2(input_mode, output_mode);
复制一个对象
struct soap *soap2 = soap_copy(soap1);
销毁对象。在堆上创建的soap对象都必须通过soap_free来销毁,这是销毁对象本身。
soap_free(soap1);
栈上创建struct soap
我们也可以在栈上创建soap对象。
struct soap soap1, soap2, soap3;
soap_init(&soap1);
soap_init1(&soap2, input_and_output_mode);
soap_init2(&soap3, input_mode, output_mode);
soap_init
C语言中,栈上创建的soap对象,需要soap_init初始化再使用。C++中构造函数已经自动调用了soap_init,见stdsoap2.cpp
#ifdef __cplusplus
soap::soap()
{
soap_init(this);
/* no logs to prevent DEBUG mode leaks when the user calls a soap_init() on this context */
soap_set_test_logfile(this, NULL);
soap_set_sent_logfile(this, NULL);
soap_set_recv_logfile(this, NULL);
}
#endif
struct soap上下文资源管理
上下文资源创建
soap_malloc
void *soap_malloc(struct soap*, size_t len)
这个函数可以在堆上分配len字节,并纳入soap对象的上下文管理。如果分配失败,返回null。这是一种没有类型的指针,需要自己去维护指针类型。
soap_memdup
void * soap_memdup(struct soap*, const void *src, size_t len)
堆上的内存拷贝,也会被soap对象上下文管理。
soap_new_T
在gSOAP 2.8.35之后,soap_new_T的方式可以直接使用。
T * soap_new_T(struct soap*, int n)
T是一个替换字符,具体可以在代码中找到合适的类型。 这个函数返回创建n个T类型的地址,如果n为负值或者1,则就创建单个对象堆地址空间并返回。这个函数在内部会调用soap_malloc(soap, n * sizeof(T))
和 soap_default_T(soap, T*) 去初始化每个对象。如果失败就返回null。
soap_strdup
复制一个字符串到上下文管理的堆地址
char *soap_strdup(struct soap*, const char *str
例如
struct ns__record *record = (struct ns__record*)soap_malloc(soap, sizeof(struct ns__record));
soap_default_ns__record(soap, record);
record->name = soap_strdup(soap, "Joe");
上下文资源释放
上下文资源释放一般就是4连发即可
soap_destroy(soap);
soap_end(soap);
soap_done(soap);
soap_free(soap);
soap_destroy
用于删除soap对象管理的上下文中创建的那些对象资源,比如类、结构体、模板类对象。比如一些反序列化生成的那些对象就必须用这个释放。它必须在soap_end(soap)之前调用。
soap_end
用于删除soap对象管理上下文中创建的那些原始数据类型,比如soap_malloc创建的那些非对象的类型——soap_destroy(soap)删除不了的那些其他堆数据。
soap_done
在C语言中,栈上的soap对象,需要使用这个函数清理相关资源。
soap_done(&soap1);
soap_free
这个函数用来释放soap对象本身,放在最后
soap_free(soap_);
C++语言的一些差异
先看一下stdsoap2.cpp中源码
#ifdef __cplusplus
soap::soap()
{
soap_init(this);
/* no logs to prevent DEBUG mode leaks when the user calls a soap_init() on this context */
soap_set_test_logfile(this, NULL);
soap_set_sent_logfile(this, NULL);
soap_set_recv_logfile(this, NULL);
}
#endif
/******************************************************************************/
#ifdef __cplusplus
soap::soap(soap_mode m)
{
soap_init1(this, m);
}
#endif
/******************************************************************************/
#ifdef __cplusplus
soap::soap(soap_mode im, soap_mode om)
{
soap_init2(this, im, om);
}
#endif
/******************************************************************************/
#ifdef __cplusplus
soap::soap(const struct soap& soap)
{
soap_copy_context(this, &soap);
}
#endif
/******************************************************************************/
#ifdef __cplusplus
struct soap& soap::operator=(const struct soap& soap)
{
soap_done(this);
soap_copy_context(this, &soap);
return *this;
}
#endif
/******************************************************************************/
#ifdef __cplusplus
void soap::destroy()
{
soap_destroy(this);
soap_end(this);
}
#endif
/******************************************************************************/
#ifdef __cplusplus
soap::~soap()
{
soap_done(this);
}
#endif
destroy()
在C语言中下面两行代码实现的功能,C++中通过函数destroy()就完成了。
soap_destroy(soap1);
soap_end(soap1);
~soap()
C++对象析构函数,完成了soap_done(&soap1) 来释放栈上管理的资源。
栈数据、静态数据
栈上分配的变量,静态数据也是可以直接用的。
struct soap *soap = soap_new(); // new context
...
struct ns__record *record = (struct ns__record*)soap_malloc(soap, sizeof(struct ns__record));
static uint64_t SSN = 1234567890UL;
soap_default_ns__record(soap, record);
record->name = "Joe";
record->SSN = &SSN; // safe to use static values: the value of record->SSN is never changed
...
soap_end(soap); // delete managed soap_malloc'ed heap data
soap_free(soap); // delete context