从托管代码调用时,C ++ DLL崩溃

时间:2011-08-16 17:18:24

标签: c# c++ memory unmanaged

有一个使用.NET Framework 3.5用C#编写的WinForms应用程序。此应用程序使用C ++ Dll,它使用以下声明导入:

[DllImport(DllName)]
public static unsafe extern int LoadDBData(String dsn, String userid, String password);

此方法使用SQL Server数据库从给定的ODBC-DSN导入数据。当数据库中的数据太多时,调用会崩溃。这个extern dll的提供者说这是因为dll无法获取更多的堆大小,我的应用程序应该提供更多的堆内存。

我怎么能解决这个问题?据我所知,从自动垃圾收集中排除组件的唯一可能性是我已经使用过的unsafe关键字。 任何想法都将不胜感激。

提前致谢

马丁

3 个答案:

答案 0 :(得分:0)

您无法在.NET中增加堆大小。 您可以使用Process.Start在.NET应用程序调用的c / c ++中创建EXE。 你的c / c ++ EXE只会调用DLL函数并返回结果(或者如果你有多个函数,它可以使用命令行参数)。如果您不想要单独的EXE,可以尝试使用RunDll32。

答案 1 :(得分:0)

这似乎是供应商库的问题,而不是您的代码。

  

托管和非托管内存应被视为完全独立。托管内存通常是在垃圾回收上分配的内存   堆,而非托管内存是其他任何东西:ANSI C内存池   通过malloc(3),自定义内存池和   在CLI实现控制之外的垃圾分配堆...

请注意,以上引用来自Mono documentation,但我相信(如果我没有记错的话)一般来说.NET也是如此。如果数据正在DLL的内部数据结构中加载,那么它应该分配自己的内存。如果您提供的缓冲区将填满数据,那么它将只填充您为缓冲区分配的数据(并在编组之前固定)。那么数据在哪里加载?

答案 2 :(得分:0)

我怀疑这是特定于.NET,托管内存,垃圾收集等。它是一个本机DLL,因此它使用常规的非托管内存。当然,.NET运行时也会使用它的内存份额,但使用DLL的本机应用程序也会这样做。

如果您在32位进程中运行,则.NET和非托管代码的总堆大小可以限制为1.5 GB。没有其他信息很难说,但你可能达到了这个限制。

因此,一个选择是询问您的供应商,他们是否有64位版本的库并切换到64进程。在64位进程中,内存几乎是无限的(根据今天的标准)。