Hi all,
I have a problem with wsdl2ws tool, to be clear with the code it
generates. I want to use an array of complex type as output of test web
service. Wsdl file is attached below. I would be glad if someone could
answer my questions, or at least point to right place where to find answers.
The structure used as array item is composed from string and integer.
The wsdl2ws generated class for this structure:
class DirItem
{
public:
xsd__string name;
xsd__int* size;
xsd__string getname();
void setname(xsd__string InValue);
xsd__int* getsize();
void setsize(xsd__int* InValue);
DirItem();
void reset();
virtual ~DirItem();
};
Question 1)
Why is the integer here stored using a pointer? (xsd__int* size)
Next question is related to generated client stub. I've written a simple
client, the code looks like this:
FileServicePortType ws("http://localhost/axis/FileService");
DirItem_Array * dir = ws.getDir("c:\\");
delete dir;
This code works, but creates a memory leak. As I investigated,
deserialization of response allocates everything on heap, but it is not
deleted.
Question 2)
Whats bad with this code? How do it correctly?
Similar situation with server-side. I've written this code as
implementation of the operation on the server:
DirItem_Array * FileServicePortType::getDir(xsd__string Value0)
{
DirItem_Array * dir = new DirItem_Array();
DirItem * item = new DirItem();
char * name = new char[128];
strcpy(name, "number1");
int * size = new int(100);
item->setname(name);
item->setsize(size);
dir->addElement(item);
return dir;
}
Again the code works, but with memory leaks. As you can see, everything
gets allocated from heap, but when I try to pass there pointers to
static variables instead of allocated on heap, the service crashes
because the axis engine later inconsistently creates copies on heap and
calls inconsistently delete on some of them.
Question 3)
What is the right way to prepare return value from this method?
And finally for the generated service wrapper class (on the server). The
snippet of code (generated) looks like this:
/*
* This method wrap the service method
*/
int FileServicePortTypeWrapper::getDir(void* pMsg)
{
.
<-- snip -->
.
xsd__string v0 = NULL;
xsd__string value0 = pIWSDZ->getElementAsString("path",0);
if (value0)
{
v0 = new char[ strlen( value0 ) + 1 ];
strcpy( v0, value0 );
Axis::AxisDelete( (void *) value0, XSD_STRING);
}
if (AXIS_SUCCESS != (nStatus = pIWSDZ->getStatus()))
{
return nStatus;
}
try
{
DirItem_Array * ret = pWs->getDir(v0);
nStatus = pIWSSZ->addOutputCmplxArrayParam(ret,(void*)
Axis_Serialize_DirItem, (void*) Axis_Delete_DirItem, (void*)
Axis_GetSize_DirItem, "getDirReturn", Axis_URI_DirItem);
delete ret;
return nStatus;
}
catch(...)
{
return AXIS_FAIL;
}
}
Here is taken an input parameter (xsd_string value0). Then its copy is
created on the heap and value0 is deleted. But the xsd_string v0 is not
cleaned up, and it produces again a memory leak.
Question 4)
Why is created a copy of value0 on the heap? And why its not deleted later?
Thanks for answers, hope someone will shed light on this.
Petr
I have this testing wsdl:
<?xml version="1.0"?>
<definitions name="fileservice"
targetNamespace="http://unicontrols.cz/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:tns="http://unicontrols.cz/"
xmlns:s="http://unicontrols.cz/xsd"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<types>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://unicontrols.cz/xsd">
<import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
<complexType name="ArrayOfDirItem">
<complexContent>
<restriction base="soapenc:Array">
<attribute ref="soapenc:arrayType" wsdl:arrayType="s:DirItem[]"/>
</restriction>
</complexContent>
</complexType>
<complexType name="DirItem">
<all>
<element name="name" type="string"/>
<element name="size" type="int"/>
</all>
</complexType>
</schema>
</types>
<message name="getDirRequest">
<part name="path" type="xsd:string"/>
</message>
<message name="getDirResponse">
<part name="listing" type="s:ArrayOfDirItem"/>
</message>
<portType name="FileServicePortType">
<operation name="getDir" parameterOrder="path">
<input message="tns:getDirRequest"/>
<output message="tns:getDirResponse"/>
</operation>
</portType>
<binding name="FileServiceBinding" type="tns:FileServicePortType">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getDir">
<soap:operation soapAction="fileservice#getDir"/>
<input>
<soap:body use="encoded" namespace="http://unicontrols.cz/"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded" namespace="http://unicontrols.cz/"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="fileservice">
<port binding="tns:FileServiceBinding" name="FileServicePort">
<soap:address location="http://localhost/axis/fileservice"/>
</port>
</service>
</definitions>