×
Namespaces

Variants
Actions

Using gsoap for web services

From Nokia Developer Wiki
Jump to: navigation, search

This article explains how to work with gsoap on Symbian - a cross-platform open source C and C++ software development toolkit that generates C/C++ RPC code, XML data bindings, and efficient schema-specific parsers for SOAP Web services.

Article Metadata
Article
Created: sinhashivam (11 Mar 2009)
Last edited: hamishwillee (30 May 2013)

Contents

Problem statement

With the time-to-market being so critical for mobile applications, One would certainly like to have as much reusable components as possible. This is where generic components come into picture.

Let us say you want to design a S60 application with SOAP/XML web services communication. Nokia provides a WSDL-to-C++ tool to generate stubs from wsdl file and Xmldatabinding libraryto run this code. However, later if you decide to port this application to UIQ( or even Samsung S60 devices), you need to re-design your application as this library is provided by Nokia and doesn't work on other platforms or even S60 devices from other manufacturers. How to avoid this problem by making the SOAP communication generic for all platforms. The answer is gsoap.

What is gSOAP

A cross-platform open source C and C++ software development toolkit. Generates C/C++ RPC code, XML data bindings, and efficient schema-specific parsers for SOAP Web services.

Why gSOAP

The primary reason to go for gSOAPis portability.gSOAP supports most platforms, including embedded systems and small OS (for example WinCE, Symbian, and PalmOS).


How to use gSOAP

Download the latest gSOAP package from the SourceForge gSOAP project site. The gSOAP distribution package includes two compiler tools to develop your applications:

'wsdl2h' WSDL parser: This tool converts WSDLs and XSD files into annotated C/C++ definitions.

'soapcpp2' stub and skeleton compiler :This tool generates RPC code and XML serializers from the annotated C/C++ definitions.

The 'wsdl2h' parser converts WSDL into gSOAP header file specifications of Web services. This specification gives a C/C++ transparent view of the server's functionality. The header file is processed by 'soapcpp2' to generate the source code stubs and skeletons to invoke the service or build a new service based on the WSDL.

Binary files location in the unzipped package

After you unzip the downloaded package, you can view the binaries of above said two tools at the path: gsoap_2.8.3\gsoap-2.8\gsoap\bin\win32 (in Windows Environment).

Step1: Generating the header file

The first step is to generate the header file from your wsdl file using the wsdl2h tool. We may need to modify the typemap.dat file to include the namespaces corresponding to our wsdl. If the namespace is unspecified, the wsd2l tool will use the default ns1...ns2 values. In essence a namespace aims to provide unique means to identify a type.

  • To run the following commands, you may need to open command prompt first and then reach to the directory where your binary files of the tools are placed. For Example, if your binaries are placed at the path D:\user\Symbian\gsoap_2.8.3\gsoap-2.8\gsoap\bin\win32

then first you have to reach to this directory in command prompt.

After you reach till the directory where your binaries are placed, you may exeute the following command

>wsdl2h -s -t typemap.dat -o soapProxy.h mywebservice.wsdl
 
-s indicates that code that relies on STL should not be generated since the STL is not available for Symbian.
 
-o specifies the output name of the file;
 
-t specifies the Specific typemap.dat to be used.
 
for more options, use wsdl2h -help

Our Example

Suppose we want to process the calc.wsdl file placed at location http://www.yoirservername.com/calc.wsdl by our wsdl2h tool to generate calc.h header file. To do this, we will execute the following command

>wsdl2h -o calc.h http://www.yoirservername.com/calc.wsdl

On successful execution this command will generate a header file named calc.h at the same location where your binary files are placed.

Step2: Generating C++ code

We need to run the soapProxy.h through the gSOAP compiler in order to create the proxy, serializers and namespace mapping file.

The soapcpp2.exe is used with the following parameters:

soapcpp2 -t -C -L soapProxy.h
 
-t indicates that code is to generate typed messages (with the xsi:type attribute).This helps ensure interoperability and compatibility when using RPC-encoded style.
 
-C indicates that only client side code should be generated.
 
-L By default the compiler will attempt to create a soapClientLib.cpp which is relevant for building static or dynamic libraries. This is not relevant to us and is therefore disabled with the -L flag.

Our Example

After we generated calc.h header file, we now need to generate the rest of the stub files. To do this, we will execute the command having following syntax

>soapcpp2 -i -C -I<path> calc.h

Here, path refers to the path of the file stlvector.h So, according to our example the command will be:

>soapcpp2 -i -C -ID:\user\Symbian\gsoap_2.8.3\gsoap-2.8\gsoap\import calc.h

After the successful execution of above command, we will be having some .h, .cpp and .xml type files at the same location where our binary files are placed.

Step3: Include generated file to your project directory

Files
FileName Description inc src
soapProxy.h Defines schema types, services & bindings X
soapStub.h Amended schema types, services & binding definitions X
soapH.h XML (de)serializers for data types X
stdsoap2.h The gSOAP runtime X
myWebServiceSOAP11BindingProxy.h Proxy to invoke the services X
myWebServiceSOAP12BindingProxy.h Proxy to invoke the services X
soapC.cpp X
soapClient.cpp X
stdsoap2.cpp X

mmp file

We need to add the directory \epoc32\include\libc in the mmp file like shown below:

USERINCLUDE    \epoc32\include\libc

Multithreading for non-blocking calls

To keep the application UI responsive, We can issue the gsoap call in a seperate thread.

void CMyUpdater::StartL()
{
TInt id = iThread2.Handle ();
if ( (id==KCurrentThreadHandle)||(id==0))
{
 
//Thread uses shared heap created within main thread
TInt err = iThread2.Create (_L("myupdater"),ThreadFunction,KDefaultStackSize,NULL,(TAny *)this);
if ( err==KErrNone)
{
iStatus=KRequestPending;
SetActive ();
iThread2.Resume ();
}
}
}
 
// protected from CActive
void CMyUpdater::DoCancel()
{
TInt id = iThread2.Handle ();
if ( (id!=KCurrentThreadHandle)&&(id!=0))
{
User::After (1000000);
/*Thread request must be indicated as completed
* when canceling the thread else the thread is blocked
* due to 'User::WaitForRequest()' in 'cancel()'
*
*/

TRequestStatus* status = &iStatus;
iThread2.RequestComplete(status, KErrCancel);
iThread2.Kill (KErrCancel);
iThread2.Close ();
 
}
}
 
void CMyUpdater::RunL()
{
if ( iStatus==KErrDied || KErrCancel)
{
//indicate the webservice response is processed - Ani
iThread2.Close ();
}
else
{
SetActive ();
}
 
}
 
 
// private new methods
TInt CMyUpdater::ThreadFunction(TAny *aPtr)
{
CMyUpdater* ptr = (CMyUpdater*)aPtr;
 
// open main thread
RThread thread;
thread.Open (ptr->iId, EOwnerProcess);
 
//Create a cleanup stack
CTrapCleanup* cleanup = CTrapCleanup::New ();
//Create and install a active scheduler
CActiveScheduler* sched(NULL);
sched=new CActiveScheduler;
if ( !sched)
{
delete cleanup;
return KErrNoMemory;
}
 
CActiveScheduler::Install (sched);
 
TRAPD(err,ptr->IssueRequestL());
 
CloseSTDLIB();
 
TRequestStatus* status = &(ptr->iStatus);
thread.RequestComplete (status, KErrDied);
 
//Delete the heap allocated stuff
delete sched;
delete cleanup;
return KErrNone;
 
}
 
 
void CMyUpdater::IssueRequestL()
{
//Issue web service request here and check for response
}
This page was last modified on 30 May 2013, at 07:36.
285 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×