在gSOAP序列化期间不了解错误

时间:2012-02-10 15:25:57

标签: c# c++ xml xml-serialization gsoap

在Windows,C#和托管C ++上使用gSoap 2.7.17。

我有(gSOAP)类描述文件数组:

class ns__ContainerFile
{
public:
    xsd__long           fileId;
    xsd__string         fileName;
};

class ContainerFileArray
{
public:
    ns__ContainerFile         *__ptr;
    int                       __size;
};

class ns__Container
{
public:
    xsd__long           containerId     0:1 = 0;
    xsd__string         name            0:1 = "";
    xsd__string         description     0:1 = "";
    ContainerFileArray* files           0:1 = NULL;
};

在托管c ++中,我分配了返回数组:

ContainerFileArray gSoapArray;
gSoapArray.__size = managedArray->Length;
gSoapArray.__ptr = (ns__ContainerFile*) soap_malloc(soap, sizeof(ns__ContainerFile) * gSoapArray.__size);

上面的代码是名为ConvertArray的方法的一部分,因此被调用:

ns__Container unManaged;
*unManaged.files = ConvertArray(soap, managed->files->ToArray());

问题是,虽然ConvertArray似乎运行正常(我可以看到数据元素看似正确地填充在malloc的内存中),但是当我们整理Web服务时,我在序列化步骤中遇到访问冲突请求(即:我们的C ++代码已发出SOAP_OK返回值,逻辑已返回到自动生成的gSOAP代码)。

当处理简单类型的数组时,整个过程工作正常 - 整数,长整数等,但是会出现更复杂的类型 - 类等。

如果在ConvertArray方法中,我替换第3行:

gSoapArray.__ptr = soap_new_ns__ContainerFile(soap, gSoapArray.__size);

分配内存,它工作正常。

所以,我不确定我理解为什么。在第一种情况下,我使用soap_malloc来分配一个ContainerFile类大小的内存块,但是托管数组中有许多元素。在第二种情况下,它归结为使用soap_new做同样的事情。如果分配的内存全部由gsoap管理,并且在其他方​​面是相同的(据我所知),为什么soap_malloc的版本在序列化期间会失败?

使用Visual Studio,我可以看到它在以下生成的代码中失败:

void ContainerFileArray::soap_serialize(struct soap *soap) const
{
    if (this->__ptr && !soap_array_reference(soap, this, (struct soap_array*)&this->__ptr, 1, SOAP_TYPE_ContainerFileArray))
        for (int i = 0; i < this->__size; i++)
        {    soap_embedded(soap, this->__ptr + i, SOAP_TYPE_IDCXDService__ContainerFile);
            this->__ptr[i].soap_serialize(soap);
        }
}

指示符位于突出显示的行上,但我怀疑它在soap_embedded调用中失败了。我还应该注意,它在malloc'd块中的第一个元素上失败了(即:当i == 0时)。

1 个答案:

答案 0 :(得分:0)

你应该经常使用&#39; new&#39;而不是&#39; malloc&#39;在C ++中,如:

gSoapArray.__ptr = soap_new_ ns__ContainerFile(soap, gSoapArray.__size);

或者甚至更好,在gSOAP头文件中使用STL std :: vector,如下所示:

#import "stlvector.h"
class ns__Container
{
public:
    xsd__long           containerId     0:1 = 0;
    xsd__string         name            0:1 = "";
    xsd__string         description     0:1 = "";
    std::vector<ns__ContainerFile> files           0:1 = NULL;
};

基本上,malloc在C ++中不安全,因为实例的VMT未初始化,因此动态方法调用会导致崩溃。