General questions and answers

What is Genivia inc?
What kind of consulting services are available?
where do I sign up for the community mailing lists for Q&A and software support?

gSOAP toolkit questions and answers

Where can I download gSOAP?
Where can I find the gSOAP licensing conditions?
How portable is gSOAP?
Does gSOAP support ANSI C?
Does gSOAP support C++ class hierarchies or the standard template library?
Is gSOAP thread safe and does it support stand-alone multi-threaded services?
Are gSOAP services and client applications secure?
What standards does gSOAP support?
How do I develop a gSOAP application from a WSDL service definition?
How do I specify input and output parameters in a service method declaration?
How do I declare a service method that has no input parameters?
How do I declare a service method that has no output parameters?
How do I specify service method parameters that are keywords such as 'return'?
How do I declare a service method for one-way asynchronous messages?
How can I specify a service method that uses SOAP 1.1 'anonymous parameter arrays'?
How do I use SOAP literal encoding with gSOAP?
How do I specify SOAP Headers?
How do I specify customized SOAP Faults?
How do I debug a gSOAP service and client application?
How do I install and debug a gSOAP service as a CGI application?
How do I use gSOAP with Apache mod_gsoap?
How do I use gSOAP with IIS?
How do I run a stand-alone gSOAP service?
How can I tell gSOAP to ignore certain data type declarations?
How can I specify primitive XSD schema types or SOAP-ENC schema types?
I get a link error in VC++. What can I do?
My code segfaults. What can I do?
How can I allocate temporary memory space in a service method?
I implemented a service method that returns a stack-allocated data structure. As a result, my gSOAP service returns the wrong values and/or crashes. What can I do?
My client/service appears to ignore data when receiving messages. What can I do?
I wrote a client/service that exchanges strings declared as char[N], but I can't receive any strings?
How can my client/service send and receive arbitrary XML documents?

What is Genivia inc?
Genivia is a private consulting and software development company specializing in Web Services and Grid computing.
back to top

What kind of consulting services are available?
Geniva specializes in Web Services solutions and provides additional support for the gSOAP toolkit and associated utilities.
back to top

How do I sign up for the community mailing lists for Q&A and software support?
There are currently two mailing lists: gsoap@yahoogroups.com for general questions and software support and support@genivia.com for software development discussions and feedback.
back to top

Where can I download gSOAP?
You can download the limited open source edition gSOAP from http://sourceforge.net/projects/gsoap2. Please visit our commercial licensing page for the standard edition and enterprise edition software.
back to top

Where can I find the gSOAP licensing terms and conditions?
Please visit our commercial licensing page for the standard edition and enterprise edition software.
back to top

How portable is gSOAP?
gSOAP includes automake/autoconf configuration and installation scripts. The toolkit runs on Mac OS X, Linux, Sun Solaris, Irix, HPUX, Tru64, Cygwin, Win32, and Palm OS, and Symbian.
back to top

Does gSOAP support ANSI C?
gSOAP supports the development of pure C Web services and client applications. The gSOAP compiler parses ANSI C.
back to top

Does gSOAP support C++ class hierarchies or the standard template library?
gSOAP supports the native C and C++ type system, including class hierarchies with single inheritance. gSOAP supports class-based polymorphism, which means that derived classes can be safely passed to service methods (provided that the service was compiled with both base and derived class definitions).
back to top

Is gSOAP thread safe and does it support multi-threaded services?
The runtime gSOAP library codes are thread safe. A multi-threaded service can be developed and deployed as a stand-alone service application. Pthreads-based service examples are included in the distribution. Multi-threaded services improve the scalability and reliability of services.
back to top

Are gSOAP services and client applications secure?
The runtime gSOAP library codes were carefully written to avoid known security problems such as buffer overrun exploits and socket vulnerabilities. You can use gSOAP with OpenSSL to encrypt your service and client communications with authentication provided by a certificate authority. In addition, WS-security is supported. A GSI (Globus Security Infrastructure) plug-in for gSOAP is also available.
back to top

What standards does gSOAP support?
See our gSOAP software fact sheet (PDF).
back to top

How do I develop a gSOAP application from a WSDL service definition?
Use the WSDL importer, wsdl2h, included in the package. It takes multiple WSDLs as file arguments or URLs and generates a unified header file for the soapcpp2 compiler.
back to top

How do I specify input and output parameters in a service method declaration?
All parameters are considered input parameters, except the last which is the output parameter. Input parameters can be passed by value or by pointer (but not by reference). The output parameter must be passed by pointer or reference and cannot be a struct or class. To specify multiple output parameters, just use a struct or class to encapsulate them. By SOAP 1.1 convention, the name of the struct/class must be the method name ending in 'Response'. Consider for example 'int ns__method(int in, float *fin, struct ns__methodResponse { int out; float fout; } *response);'.
back to top

How do I declare a service method that has no input parameters?
Specify just one output parameter in the function prototype of the service method. Some C and C++ compilers will not compile the gSOAP-generated codes which is due to the empty struct produced by gSOAP. To circumvent this problem, use void* as a dummy input parameter, as in 'int ns__myMethod(void*, int &return_);'. The void* parameter is not considered an input parameter because it cannot be encoded.
back to top

How do I declare a service method that has no output parameters?
Specify an output parameter that is an empty struct. For example 'int ns__myMethod(..., struct ns__myMethodResponse { } &response);'. Some C/C++ compilers will not compile this empty struct. To avoid this problem, use void* as a dummy field, as in 'int ns__myMethod(..., struct ns__myMethodResponse { void *dummy; } &response);'. This void* field will not be (de)serialized because it cannot be encoded.
back to top

How do I specify service method parameters that are keywords such as 'return'?
Use parameter names that end in underscore(s). You can also use this convention with type names, struct fields, class members, and so on to avoid name clashes with keywords. The underscore(s) are not significant to gSOAP and will not be used in the SOAP/XML payload. Consider for example 'int ns__mymethod(int &return_);', which declares a service method with one output parameter 'return_' encoded as '<return>' in XML.
back to top

How do I declare a service method for one-way asynchronous messages?
Specify a 'void' output parameter in the service method function prototype, as in 'int ns__method(..., void);'. gSOAP will produce the client-side send and receive routines 'int soap_send_ns__method(struct soap*, ...)' and 'int soap_recv_ns__method(struct soap *, struct ns__method *)', respectively. In addition, the server-side service routine 'int soap_serve(struct soap*)' will accept one-way messages without returning a response.
back to top

How can I specify a service method that uses SOAP 1.1 'anonymous parameter arrays'?
Specify the service method function prototype without filling in the parameter names.
back to top

How do I use SOAP literal encoding with gSOAP?
Add the gSOAP-directive '//gsoap ns service encoding: literal' to your header file, where 'ns' is the namespace prefix of your service methods ('int ns__method(...);').
back to top

How do I specify SOAP Headers?
Specify a 'struct SOAP_ENV__Header' in your header file that contains the appropriate fields. Each field should be namespace qualified (e.g. 'int h__transaction'). In your client/service code, set the 'soap.header' pointer before transmitting a message, for example 'soap.header = soap_malloc(&soap, sizeof(struct SOAP_ENV__Header));' and set the fields.
back to top

How do I specify customized SOAP Faults?
Specify a 'struct SOAP_ENV__Fault' in your header file that contains the appropriate fields. You must specify the fields 'char *faultcode; char *faultstring; char *faultactor; struct SOAP_ENV__Code *SOAP_ENV__Code; char *SOAP_ENV__Reason;' (see the soapcpp2-generated file soapStub.h). In your client/service code, set the 'soap.fault' pointer before transmitting a message, for example 'soap.fault = soap_malloc(&soap, sizeof(struct SOAP_ENV__Fault));' and set the fields.
back to top

How do I debug a gSOAP service and client application?
Uncomment '#define DEBUG' in stdsoap2.h and recompile your application. When you run your application, three files are created in the current directory: SENT.log, RECV.log, and TEST.log. All output messages are appended to SENT.log, all input messages are appended to RECV.log, and TEST.log contains various logging messages generated by the gSOAP runtime. You can also compile stdsoap2.cpp with C/C++ compiler options '-DDEBUG'. You can also dump a client request message to stdout with the endpoint URL "http://" in the call. The client will wait for input from stdin.
back to top

How do I install and debug a gSOAP service as a CGI application?
Create an executable service application and place it in the Web server's cgi-bin directory, or rename the executable with file extention .cgi and place it in your public_html directory. Enable the executable file permissions. To debug, compile stdsoap2.cpp with compiler option -DDEBUG or uncomment '#define DEBUG' in stdsoap2.h and recompile. Create empty SENT.log, RECV.log, and TEST.log files with write permission in the executable directory. Alternatively, you can redirect a SOAP/XML message to the executable. For example, 'myservice.cgi < request.soap' to test the service. Note that CGI-based services are easy to write but not very efficient. The main body of the application consists of just a call to 'soap_serve(soap_new());'.
back to top

How do I use gSOAP with Apache mod_gsoap?
Apache mod_gsoap is a separate package. You will need to download the platform-independent version of gSOAP and follow the instruction that come with Apache mod_gsoap
back to top

How do I use gSOAP with IIS?
The IIS module for gSOAP is a separate package. Follow the instruction provided with this package
back to top

How do I run a stand-alone gSOAP service?
To build industrial-strength services, you can use Apache mod_gsoap or the IIS package. Because gSOAP includes an HTTP stack, you can also deploy a gSOAP service as a stand-alone application, which requires the use of a thread package such as pthreads. Some example multi-threaded stand-alone example services are provided with the gSOAP distribution. You can run the service as a background process listening to client request messages on a port.
back to top

How can I tell gSOAP to ignore certain data type declarations?
You can provide the type declarations in the header file and use the 'extern' qualifier or you can enclose the type declarations within [ and ] to make them transient, that is, invisible to the gSOAP serializers. For example:

extern class ostream; // can't be encoded: transient
class ns__foo
{ public:
  char *s;
  struct soap *soap; // special field
  ns__foo();
[ ns__foo(const char *t); // transient constructor
  print(ostream &s); // transient method
]
}; 

with for example the following implementation of the service method 'ns__foo':

ns__foo::ns__foo(const char *t)
{ s = (char*)soap_malloc(soap, strlen(t)+1);
  strcpy(s, t);
}

The 'struct soap* soap' field in this class is a special field set by gSOAP's deserializers and the gSOAP-generated 'soap_new_ns__foo()' function to instantiate this class.
back to top

How can I specify primitive XSD schema types or SOAP-ENC schema types?
Use typedef declarations for primitive types in the header file input to the compiler. For example, to declare an XSD schema string type, declare 'typedef char *xsd__string;' and use the 'xsd__string' type for service method parameters and compound data structures. See the documentation for more details on primitive XSD schema types and the section on SOAP literal encoding. The declaration of SOAP-ENC schema types is similar. For example, 'typedef char *SOAP_ENC__string' declares a SOAP-ENC:string schema type.
back to top

I get a link error in VC++. What can I do?
Change all .c into .cpp extensions. Link your application with soapC.cpp ,soapClient.cpp (or soapServer.cpp for services), and stdsoap2.cpp . Check the actual-formal parameter passing (the file soapStub.h contains the prototypes of the generated functions).
back to top

My code segfaults. What can I do?

  1. Make sure that the gSOAP run-time environment (struct soap) is initialized by calling 'soap_init(struct soap*)' or created with 'struct soap *soap_new()'.
  2. Make sure you don't pass the gSOAP run-time environment (struct soap) by value to your application functions. Always pass struct soap by reference or pointer, just like the internal gSOAP functions do. In case you need to make a copy of it, use 'struct soap *soap_copy(struct soap*)'.
  3. Make sure all pointers that are used in the data structures that you pass as parameters to service methods are initialized, that is, pointers should be NULL or point to a valid object. When this is not the case, a crash will occur in the 'soap_serialize_T' and/or 'soap_mark_T' routines of data type 'T'.
  4. Make sure all class instances that are passed as parameters to remote methods are initialized, that is, their virtual method tables (VMTs) must be set.
  5. Make sure that no two (or more) threads can access the same gSOAP run-time environment (struct soap) concurrently. Use separate run-time environments in threads.
  6. Remove all calls to 'soap_destroy(struct soap*)' and 'soap_end(struct soap*)' and rerun to check if the segfault results from gSOAP's garbage collection cleanup.
  7. If the segfault occurs in the 'soap_destroy(struct soap*)' cleanup, remove all deallocation calls in the class' destructors to avoid duplicate deallocations (one by the destructor and one by gSOAP's cleanup). Compensate the elimination of deallocation calls by allocating data solely with 'soap_malloc(struct soap*, size_t)' and 'soap_new_Class(struct soap*, int)' routines in your code. Alternatively, you can use 'soap_unlink(struct soap*, void*)' in the class destructors to unlink the data from gSOAP's deallocation chain before deallocating it in the class destructor (see the gSOAP documentation).
  8. If the segfault occurs in the 'soap_end(struct soap*)' cleanup, then it is likely that data is already deallocated with 'free()' in your code and deallocated again in 'soap_end(struct soap*)'. Use 'soap_unlink(struct soap*, void*)' to unlink the data from gSOAP's deallocation chain before freeing it up.

back to top

How can I allocate temporary memory space in a service method?
See the question and the answer below.
back to top

I implemented a service method that returns a stack-allocated data structure. As a result, my gSOAP service returns the wrong values and/or crashes. What can I do?
Use function 'void *soap_malloc(struct soap *soap, size_t n);' to allocate memory on the heap that will be released upon calling 'soap_end()', for example after calling 'soap_serve()' in your service:

int main()
{ ...
  soap_serve(&soap);
  soap_end(&soap);
  ...
} 

Here is an example service method that allocates a temporary string:

int ns__itoa(struct soap *soap, int i, char **a)
{ *a = (char*)soap_malloc(soap, 11);
  sprintf(*a, "%d", i);
  return SOAP_OK;
}

Note that you don't want to use local function variables to store values such as strings, because the values are allocated on the stack and deallocated when the function returns. Serialization of the values takes place after the return. This allocation with 'soap_malloc()' can also be used to allocate strings for the SOAP Fault data structure, for example:

int ns__mymethod(struct soap *soap, ...)
{ ...
  if (exception)
  { char *message = (char*)soap_malloc(soap, 1024);
    char *details = (char*)soap_malloc(soap, 1024);
    sprintf(message, ...);
    sprintf(details, ...);
    return soap_receiver_fault(soap, message, details);
  }
  ...
}

back to top

My client/service appears to ignore data when receiving messages. What can I do?
SOAP RPC encoding allows optional elements to be ignored. As a side effect, a namespace mismatch and/or tag name mismatch will result in dropping the element. If the namespace and/or tag name are defined correctly, data will never be dropped at run time. To assist debugging and to catch dropped elements, call 'soap_set_imode(&soap, SOAP_XML_STRICT);' to set this option in your code before making a client call or before calling 'soap_serve()'. This will enforce strict validation of messages to catch unrecognized elements and namespaces. Another way to control the dropping of elements is to define the 'fignore' callback. For example:

int main()
{ struct soap soap;
  soap_init(&soap);
  soap.fignore = mustmatch; // new callback
  ...
  soap_done(&soap); // reset callbacks
}
int mustmatch(struct soap *soap, const char *tag)
{ return SOAP_TAG_MISMATCH; // must handle all tags
} 

The 'tag' parameter contains the offending tag name. With this, you can also selectively return a fault:

int mustmatch(struct soap *soap, const char *tag)
{ if (soap_match_tag(soap, tag, "ns:login*"))
    return SOAP_OK;
  return SOAP_TAG_MISMATCH;
}

back to top

I wrote a client/service that exchanges strings declared as char[N], but I can't receive any strings?
When you use a fixed-size array of chars, the array is encoded as an array of bytes and not a string. Always use char* (or wchar_t*) for strings. gSOAP does not support fixed-size string arrays, because the actual data received may not fit the array which can lead to data loss.
back to top

How can my client/service send and receive arbitrary XML documents?
By declaring:

typedef char *XML;

or

typedef wchar_t *XML; 

and use either XML type to exchange XML in string form. When you have an XML schema, you may want to define the necessary data structures in a gSOAP header file to encode the XML.
back to top

Copyright © 2003 Genivia inc. All rights reserved. Last modified Monday, November 16, 2009