2011-08-16 111 views
2

有一个使用.NET Framework 3.5以C#编写的WinForms应用程序。此应用程序使用其使用下面的声明导入的C++ DLL:从给定的ODBC的DSN使用SQL Server数据库从托管代码调用时,C++ DLL崩溃

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

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

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

在此先感谢

马丁

回答

0

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

托管和非托管内存应该被认为是完全独立的。托管内存通常是分配在垃圾回收堆上的内存,而非托管内存则是其他任何内容:通过malloc(3)分配的ANSI C内存池 ,自定义内存池和 CLI以外的垃圾分配堆执行...

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

+0

我也认为这是供应商的库问题。但是,由于我主要以托管代码开发,供应商使他的意见不安。 但我试图从excel makro调用库,它也崩溃了。所以我相信这不是我在C#中调用的问题。 –

0

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

0

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

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

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

相关问题