2011-02-01 78 views
1

我使用从C++代码编译的dll(LPSolve,请参阅http://lpsolve.sourceforge.net/5.5/),它来自我的C#代码。我使用API​​来构建线性编程模型,然后解决它。我打电话的功能,如:当我调用DLL中的函数时会发生什么

[DllImport("lpsolve55.dll", SetLastError = true)] 
public static extern bool add_columnex 
      (int lp, int count, double[] column, int[] rowno); 

我不知道会发生什么,memorywise,当我把这样的功能,并且我在托管代码许可范围内创建了整数和数组(在C#代码)。他们是否有资格进行垃圾回收?这对C++代码意味着什么?或者不合格,在这种情况下:为什么?

回答

2

因为函数原型使用普通的旧数据类型和数组,所以这些值的内存被固定到位,然后本地代码直接作用于数据。然后,当函数返回时,内存被取消固定并且可以被垃圾收集。

换句话说,他们从不离开范围。

就C++代码而言,如果需要存储任何数据,那么它需要获取传入数据的副本,然后管理该存储器本身。

1

如果您的应用程序在使用它一段时间(过去垃圾收集)后没有发生AccessViolationException崩溃,那么假设非托管代码创建了传递它的数组元素的副本是非常安全的。这是正常的事情,这个库本来也很难从本地代码中使用。还应该有一个API函数,可以让你清除或重新初始化模型,应该释放内存。

2

我觉得Nick已经涵盖了基本部分,这只是为了增加更多的信息。 int/double数组被视为blittable类型(在托管/非托管世界中具有相同布局的类型) - 这些通常在组合时被锁定。所以你不需要关于GC。此外,你已经做了什么指示按值传递数组 - 在这种情况下,编组将这视为In参数 - 如果您的非托管dll要更新数组中的值,那么我建议您将其标记为In/Out参数(例如[In, Out]double[] column)。欲了解更多信息:

  1. Blittable和非Blittable型: http://msdn.microsoft.com/en-us/library/75dwhxf7.aspx
  2. 复制和钢钉:http://msdn.microsoft.com/en-us/library/23acw07k.aspx
  3. 编组站阵列:http://learning.infocollections.com/ebook%202/Computer/Programming/General/Programming.With.Microsoft.Dot.NET/LiB0948.htm
0

C或C++函数的原型是这样:

bool add_columnex(int lp, int count, double[] column, int[] rowno); 

Th e参数lp和count按值传递。参数列和rowno也是按值传递的,但实际数据是通过引用传递的,函数add_columnex将不得不取消列和rowno。只有在函数调用过程中才允许这种失真。当函数返回时,这些参数超出范围。这种消歧必须在界面的契约中。

当函数返回所有参数超出范围时,并不意味着该函数在调用后可以做任何事情。如果函数存储参数的副本,即双或rowno数组的地址,则合同必须允许该参数。在这种情况下,你会遇到麻烦。一个更好的契约是该函数必须复制解引用的数据。

相关问题