【发布时间】: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