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

本文关键字:DLL 崩溃 c++ 托管代码 调用 | 更新日期: 2023-09-27 18:05:40

有一个使用。net Framework 3.5用c#编写的winforms应用程序。此应用程序使用c++ Dll,该Dll通过以下声明导入:

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

该方法使用SQL Server数据库从给定的ODBC-DSN导入数据。当数据库中的数据过多时,调用会崩溃。这个外部dll的提供者说,发生这种情况是因为dll无法抓取更多的堆大小,我的应用程序应该提供更多的堆内存。

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

Thanks in advance

马丁

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

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

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

注意,上面的引用来自Mono文档,但我相信(如果我没弄错的话)对于一般的。net来说也是如此。如果数据是在DLL的内部数据结构中加载的,那么它应该分配自己的内存。如果您提供的缓冲区将被数据填满,那么它只会被您为缓冲区分配的数据填满(并在编组之前固定)。那么数据在哪里被加载呢?

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

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

如果你在一个32位进程中运行,. net和非托管代码的总堆大小可以限制在1.5 GB。如果没有额外的信息,很难判断,但你可能已经达到了这个极限。

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