从C++获取字符串数组时在C#中出现System.OutOfMemoryException异常

12

我的C++函数

    void FillArray(wchar_t** arr)
    {
         // some code
         for(i= 0;i<end;++i)
         {
             wcsncpy(arr[i],InforArray[i],MaxLength);
             count++;
         } 
     }

我的 C# 签名是

[DllImport("Native.dll", CharSet = CharSet.Unicode,EntryPoint = "FillArray")]
        internal static extern void FillArray(
            [MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.LPWStr)] 
            IntPtr[] OutBuff);

同时给出C#代码本身:

int maxLen = 256;


int count = GetPropertyCount(ref eData);
IntPtr[] buffer = new IntPtr[count];
for (int i = 0; i < count; i++)
     buffer[i] = Marshal.AllocHGlobal(maxLen);

FillArray(buffer);

string[] output = new string[count];

for (int i = 0; i < count; i++)
{
      output[i] = Marshal.PtrToStringUni(buffer[i]); 
      Marshal.FreeHGlobal(buffer[i]);
}

c++循环中没有问题地填充了数据,但是当退出FillArray时,我收到了"System.OutOfMemoryException"类型的未处理异常。

有什么想法吗?


2
你尝试分配多少内存?如果将其限制在几个字节这样小的值,它是否能正常工作? - Brian Dishaw
@SharonL - 我希望你记得在哪里定义了调用约定(只是好的代码)。 - Security Hound
你的帮助太多了。移除[MarshalAs]属性,这样PInvoke marshaller就不会尝试释放字符串。不太确定为什么会导致OOM。 - Hans Passant
3
如果wchar超过1个字节,则256字节的最大长度不足以容纳256个wchar。 - user215054
GetPropertyCount 函数是做什么的(假设它不是 .NET 框架的一部分,因为我在 MSDN 上找不到它作为一个纯函数)?异常抛出的是哪一行? - foxy
显示剩余3条评论
1个回答

2
鉴于你遇到的异常性质,程序尝试分配内存失败,在你的示例代码中有两个地方出现了这种情况,即 Marshal.AllocHGlobal()Marshal.PtrToStringUni()。因此,除非 GetPropertyCount() 以某种方式返回 Int.MaxValue,否则该程序很可能会失败,因为 wcsncpy 没有将复制的字符串置于空终止符。因此,调用 Marshal.PtrToStringUni() 将分配所有机器的内存,试图确定复制的字符串实际上在哪里结束。尝试使用允许您提供要复制的字符数的 PtrToStringUni API。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接