2D数组跨语言C ++和C#

时间:2010-11-14 02:34:16

标签: c# c++ interop

如果我想调用返回2d数组的外部C ++函数,我会遇到什么样的问题?例如,如果我在C ++函数中声明2D数组并在C ++函数中初始化数组的大小,那么.Net自动垃圾收集器将如何处理这个?我是否必须给它一个执行垃圾收集的功能,如果是,我如何从C#程序中调用它?

3 个答案:

答案 0 :(得分:2)

除非函数返回一个或多个向量,否则它在C ++中也是完全相同的问题。这是一个内存管理问题,函数的调用者没有很好的方法来释放数组的内存,它不知道数组大小也没有使用什么分配器。就此而言,即使迭代阵列也是危险的。您无法在C ++中修复的问题也无法在托管互操作中修复。

你以相同的方式解决它,你让调用者提供数组,由被调用者填充。

请注意,托管数组没有此问题,它们就像vector<>一样。从函数返回托管数组不是问题。 C ++ / CLI可以做到这一点,是解决困难的互操作问题的标准解决方案。 SAFEARRAY也是一个解决方案,在管理声明中用[MarshalAs]告诉P / Invoke marshaller他们。

答案 1 :(得分:0)

  

.Net自动垃圾收集器如何处理这个?

它不会,它与本机应用程序分配的内存无关。您可以将数组的副本返回到C#模块,并处理该问题。如果它非常大,这将是一个问题......好吧,也许其他人有一个更好的建议,因为我还没有必须越过那座桥=)。您可能会在C ++代码中分配和销毁它,并返回指向C#模块的指针。但是要小心,就像我说的那样,我不必做这样的事情。

答案 2 :(得分:0)

我知道对于简单类型(例如字符串),interop将创建非托管对象的副本并将其封送回调用者。此时,CLR将尝试通过调用CoTaskMemFree()来清理内存。这是否成功取决于内存的分配方式。如果可以,请使用CoTaskMemAlloc()分配内存,这将允许对CoTaskMemFree()的调用成功。

我已经读过,释放内存的失败将导致XP泄漏,但会在Vista和Win7中引发异常......无法说明其有效性。

对于更复杂的类型,例如数组,我不确定这是否成立。但是,一篇很好的释放内存的方法在文章here中。

它的要点是将数据作为IntPtr传回,然后从被调用的dll中公开一个名为FreeMemory()的方法,该方法获取IntPtr并释放在那里分配的内存。

HTH,
詹姆斯