从 C# 中的C++ DLL 获取回调时,WinXP 中的内存限制是多少?

What's the memory limit in WinXP when getting a callback from a C++ DLL in C#?

本文关键字:内存 多少 WinXP C++ 中的 DLL 获取 回调      更新时间:2023-10-16

我有一个使用非托管c++ DLL的c#应用程序。我发现当我从c++ DLL传递回来的内存太大时,只发生在WinXP(不是Win7)中崩溃。

基本流程是c#通过调用start函数在c++ DLL中启动一个操作,该函数提供了一个回调函数。然后,c++ DLL执行该操作并将日志信息转储到文本缓冲区中。当操作完成后,c++ DLL调用回调函数并将文本缓冲区作为参数传递:

c++:

typedef void (CALLBACK *onfilecallbackfunc_t)(LPCWSTR);
DLL_API void NWAperture_SetOnFileCallback(onfilecallbackfunc_t p_pCallback);
l_pFileCallback(_wstringCapture.c_str());
c#:

public delegate void FileCallback([MarshalAs(UnmanagedType.LPWStr)] string buffer);
public static extern void SetOnFileCallback(FileCallback fileCallback);
private void OnFile(string buffer);

这在Win7中工作得很好,但在WinXP中,如果缓冲区太大就会崩溃。我不确定导致这种情况的确切大小,但我已经设置了8MB的限制,崩溃已经消失了。

有谁知道在WinXP中可以在c++和c#之间传输的内存量的限制吗?还是我完全误解了这个问题,还有更合理的解释?

更新:我应该更具体-这发生在WinXP和Win7双启动的同一台PC上,都是32位操作系统

所以最后证明我是个白痴。为了使日志大,但加快测试速度,我点击取消按钮,它调用了c++ DLL中的一个函数,该函数停止执行,并调用了回调函数与"中止"错误和任何日志已经记录。但是当我这样做的时候,执行并没有立即停止,所以当带有日志的回调正在进行时,c++代码可能会尝试添加到日志中。这导致了我所看到的不稳定。

我通过在日志周围使用临界区来修复它。

您可以在实际耗尽RAM之前耗尽连续内存。这是使用数组缓冲区的一个很大的缺点。LinkedLists(或使用分块的数组)有助于缓解这个问题,因为你需要的空间不必是连续的。

因此,除非您的应用程序使用2+ GB的RAM,否则您的问题更可能是内存碎片。

Windows 7可能是管理内存不同于Windows XP,这可能是为什么你没有看到问题在那里。但是如果推送更多的数据,我相信你也会遇到同样的问题。

您可以设置perfmon来跟踪/记录系统的内存使用情况,设置任务管理器来跟踪应用程序。

我不知道Windows或NETFX设置了任何硬限制,但我高度怀疑从您的c++应用程序返回的数据量可能完全是任意的,这可能导致不稳定的行为。

我强烈建议考虑将日志数据写入本机组件中的文件,然后从托管代码中读取该文件。这样,无论记录了多少数据,托管代码都可以解析它,而不必担心会破坏它的堆。