C++从托管代码调用时 DLL 崩溃
有一个使用 .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 关键字。 任何想法将不胜感激。
预先感谢
马丁
there's a WinForms-application written in C# using .NET Framework 3.5. This application uses a C++ Dll which is imported using the following declaration:
[DllImport(DllName)]
public static unsafe extern int LoadDBData(String dsn, String userid, String password);
This method imports data from a given ODBC-DSN using a SQL Server database. The call crashes when there is too much data in database. The provider of this extern dll said this happens because the dll is unable to grab more heap size and my application should provide more heap memory.
How could I solve this problem? As far as I know the only possibility to exclude a component from automatic garbage collection is the unsafe keyword which I already used.
Any idea would be appreciated.
Thanks in advance
Martin
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这似乎是供应商的库的问题,而不是您的代码的问题。
请注意,上面的引用来自 Mono 文档< /a>,但我相信(如果我没记错的话).NET 一般来说也是如此。如果数据被加载到 DLL 的内部数据结构中,那么它应该分配自己的内存。如果您提供的缓冲区将被数据填满,那么它只会填满您为缓冲区分配的数据(并在编组之前固定)。那么数据加载到哪里了呢?
This seems like a problem with the vendor's library, rather than your code.
Note that the above quote is from the Mono documentation, but I believe (if I'm not mistaken) the same is true for .NET in general. If the data is being loaded in the DLL's internal data structures, then it should allocate its own memory. If you're providing a buffer which will get filled up with the data, then it will only get filled up with as much data as you've allocated for the buffer (and pinned before marshalling). So where is the data being loaded?
您无法增加 .NET 中的堆大小。
您可以使用 c/c++ 创建一个 EXE,您的 .NET 应用程序可以使用 Process.Start 调用该 EXE。
你的 c/c++ EXE 只会调用 DLL 函数并返回结果(或者如果你有多个函数,它可能需要一个命令行参数)。如果您不需要单独的 EXE,您可以尝试使用 RunDll32。
You can't increase the heap size in .NET.
You could create an EXE in c/c++ that your .NET app calls using Process.Start.
Your c/c++ EXE would just call the DLL function and return the result (or if you have more than one function it could take a command line parameter). If you don't want a separate EXE you could try using RunDll32 instead.
我怀疑这是特定于.NET、托管内存、垃圾收集等的。它是一个本机 DLL,因此它使用常规的非托管内存。当然,.NET 运行时也将使用它的内存共享,但使用 DLL 的本机应用程序也会执行相同的操作。
如果您在 32 位进程中运行,.NET 和非托管代码的总堆大小可能会限制为 1.5 GB。如果没有其他信息,很难判断,但您可能已经达到了该限制。
因此,一种选择是询问您的供应商,他们是否有 64 位版本的库并切换到 64 位进程。在 64 位进程中,内存几乎是无限的(根据当今的标准)。
I doubt this is specific to .NET, managed memory, garbage collection etc. It's a native DLL so it uses regular, unmanaged memory. Of course, the .NET runtime will also use it's share of memory but a native application using the DLL would do the same.
If you're running in a 32 bit process, the total heap size for .NET and unmanaged code can be limited to 1.5 GB. It's difficult to tell without additional information, but you might have hit that limit.
So one option would be to ask your vendor, whether they have a 64 bit version of the library and switch to a 64 process. In a 64 bit process, memory is almost unlimited (according to today's standard).