【问题标题】:Don't Understand Error During gSOAP Serialization不了解 gSOAP 序列化期间的错误
【发布时间】:2012-02-10 15:25:56
【问题描述】:

在 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 代码)。

整个过程在处理简单类型数组(int、long 等)时运行良好,但在处理更复杂类型(类等)时会崩溃。

如果在 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 时)。

【问题讨论】:

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


    【解决方案1】:

    在 C++ 中,您应该始终使用“new”而不是“malloc”,如下所示:

    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 未初始化,因此动态方法调用会导致崩溃。

    【讨论】:

    • 很抱歉,您能否用更简单的方式解释您的最后一条评论?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-01
    • 2012-09-18
    • 2014-03-31
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    相关资源
    最近更新 更多