Symbian中gSOAP 学习总结

来源:互联网 发布:数据标准化的通俗理解 编辑:程序博客网 时间:2024/05/17 22:39
gSOAP的官方网站是:http://gsoap2.sourceforge.net/
 
下面只对在symbian环境下使用略说几点。
我下载的是最新版的v2.7.10,下载的压缩包里就有一个symbian目录,里面是在symbian的例子,可以参考。
试着做了一个HelloWorld,访问web service,按照它的例子步骤如下:
1.解开软件压缩包。
 
2.根据wsdl生成代码存根等H/CPP文件。在命令行进入gsoap/bin/win32 目录,先后执行以下指令:
wsdl2h -s -o pservice.h  http://192.168.0.201/uim/pservice.asmx?WSDL  
 //  http地址根据你的接口而定,http://yourwebservice?wsdl---生成wsdl
在当前目录得到一个pservice.h文件。
 
 soapcpp2 -CLwx pservice.h
在当前目录得到多个源文件,每个文件的具体作用含义大家可以看官方资料。
 
3.在Carbide C++中新建一个工程,我就叫它HelloWsTwo,直接用了那个HelloWorld模板框架。然后将步骤2生成的几个文件弄过去,首先将soapH.h/soapStub.h/soapPServiceSoapProxy.h拷到工程的inc目录下,将soapC.cpp/soapClient.cpp拷到工程的src目录下。
4.还有两个文件在gsoap目录下,stdsoap2.h和stdsoap2.cpp,也拷入相应目录,这里其实按例子中的readme说明是不拷的,而是在mmp中修改一下指过来,不过,因为我们需要修改这个cpp所以方便起见,还是拷过去吧,省得跟其它工程弄混了。
 
5.先修改HelloWsTwoUi这个类,在头文件中增加如下代码:

#include "soapPServiceSoapProxy.h"   //根据你的接口而命名
     
class CHelloWSTwoAppView;  
class PServiceSoap;   
    
private:  
 
CHelloWSTwoAppView* iAppView;  
 
PServiceSoap * iService;   
 
 
#include "soapPServiceSoapProxy.h"
// FORWARD DECLARATIONS
class CHelloWSTwoAppView;
class PServiceSoap;
 
private:
CHelloWSTwoAppView* iAppView;
PServiceSoap * iService;
 
 
然后加一个PServiceSoap类型的成员变量iService。接着修改cpp文件,在构造时new它,在析构时delete它即可。
 
 
// .h. cpp 文件中的根据你实际的调用而编写,每个人的接口定义不同,实际情况不同。 
如果把自己的部分写出来却不符合你工程的实际情况,那就是误人之弟了。
毕竟我也吃过这样的亏,照搬网络上,白白浪费了2天时间。
 
 
6.现在还要修改mmp文件,carbide是会自动帮你加上几个源文件的,接受即可。此外,mmp中更需要增加一个包含目录include/libc,以及几个链接库,如下:
SYSTEMINCLUDE /Epoc32/include/libc LIBRARY eexe.lib estlib.lib ecrt0.lib
CAPABILITY ReadUserData NetworkServices nostrictdef    // 能力
 
7.就这么容易,但是编译时,不行,出错了!报undefined _soap_outLONG64之类的错误!!
这时开始就折腾了我差不多一天。其实修改也挺简单的,打开那个stdsoap2.cpp,我们发现其实这个函数是有的,只是被一个宏WITH_LEAN给关掉了,所以打开即可。但是打开宏,错误更多了,没办法,只能将这个函数定义前的宏注释掉看看,两个错变成三个错了,硬着头皮继续,在stdsoap2.cpp中注掉多个#ifndef WITH_LEAN的条件,终于不再报错了。
 
一切运行也就正常了。这个错误实在是够变态的了吧。
总结一下: 1.建议将stdsoap2.*弄到工程里去,因为改了源代码应该会与PC平台的应用相冲突,当然假如你并不打算将gSOAP用于symbian以外的场合,可以仍放在gsoap目录下。
2.用gsoap最大的好处是不用自己去解析那个soap响应,也不用自己去封装soap请求了。
 
//该文章是从网络上转帖而来的,就是根据自己的操作经验,添加了部分注解,以方便理解少走弯路!
内存泄露
写了个GSoap2.7.10的服务器小程序,代码很简单:
    RecSoapBindingService svr;
    int m = svr.bind(0, 80, 100);
    if(m<0)
    {
        soap_print_fault(&svr, stderr);
        return 0;
    }
   
    fprintf(stderr, "Socket connection successful: master socket = %d/n", m);
   
    for(;;)
    {
        m = svr.accept();
        if (m < 0)
        {
            soap_print_fault(&svr, stderr);
            exit(-1);
        }
        fprintf(stderr, "Socket connection successful: slave socket = %d/n", m);
        svr.serve();
        //break;
    }
    测试发现有内存泄漏问题:压力测试下看见内存一直在涨,但正常退出(通过在循环中加break使程序正常结束)时内存能够释放完全(VC环境中没有检测到内存泄漏);Debug与Release版本都是这样。
    GSoap官方网站上(http://www.cs.fsu.edu/~engelen/soap.html)有一段说明,不知道针对哪个版本:
The gSOAP engine uses a memory management method to allocate and deallocate memory. The deallocation is performed with soap_destroy() followed by soap_end(). However, when you compile with -DDEBUG or -DSOAP_MEM_DEBUG then no memory is released until soap_done() is invoked. This ensures that the gSOAP engine can track all malloced data to verify leaks and double frees in debug mode. Use -DSOAP_DEBUG to use the normal debugging facilities without memory debugging. Note that some compilers have DEBUG enabled in the debug configuration, so this behavior should be expected unless you compile in release config.
        于是在 svr.serve();后加入代码:
        soap_destroy(&svr);
        soap_end(&svr);
        问题解决——与说明不符的是,没发现Debug版与Release版的区别。
        也可以直接调用svr.run()避免这一堆处理。

内存泄露出处:http://blog.csdn.net/netnote/archive/2008/11/25/3367741.aspx
原创粉丝点击