[英]Don't Understand Error During gSOAP Serialization
在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块中的第一个元素上失败(即:当i == 0时)。
在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尚未初始化,因此动态方法调用会导致崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.