Подтвердить что ты не робот

Какой предел памяти в WinXP при получении обратного вызова из С++ DLL в С#?

У меня есть приложение С#, которое использует неуправляемую DLL на С++. Я обнаружил сбой, который происходит только в WinXP (не Win7), когда память, которую я передаю из библиотеки С++, слишком велик.

Основной поток - это то, что С# запускает операцию в С++ DLL, вызывая функцию запуска, в которой он обеспечивает обратный вызов. Затем DLL С++ выполняет операцию и записывает информацию о регистрации в текстовый буфер. Когда операция завершена, С++ DLL вызывает обратный вызов и передает текстовый буфер в качестве параметра:

С++:

typedef void (CALLBACK *onfilecallbackfunc_t)(LPCWSTR);
DLL_API void NWAperture_SetOnFileCallback(onfilecallbackfunc_t p_pCallback);

l_pFileCallback(_wstringCapture.c_str());

С#:

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

private void OnFile(string buffer);

Это отлично работает в Win7, но в WinXP, если буфер становится слишком большим, он сбой. Я не уверен в точных размерах, которые приводят к этому, но я наложил на него ограничение в 8 МБ, и авария исчезла.

Кто-нибудь знает о пределе объема памяти, который может быть передан между С++ и С#, как это в WinXP? Или я полностью неправильно понял эту проблему и там более логичное объяснение?

Обновление: я должен был быть более конкретным - это происходит на том же ПК с двойной загрузкой WinXP и Win7, как с 32-разрядной ОС.

4b9b3361

Ответ 1

Итак, в итоге оказалось, что я идиот. Чтобы сделать журнал большим, но ускорить тестирование, я нажал кнопку отмены, которая вызвала функцию в С++ DLL, которая прекратила выполнение, и вызвала функцию обратного вызова с ошибкой "abort" и тем, что уже был записан. Но когда я это сделал, выполнение не прекратилось немедленно, поэтому, когда был выполнен обратный вызов с журналом, код С++ может попытаться добавить в журнал. Это вызвало нестабильность, которую я наблюдал.

Я исправил его, используя критический раздел вокруг журнала.

Ответ 2

У вас может закончиться непрерывный путь памяти до того, как вы на самом деле закончите RAM. Это одна большая сторона использования буферов Array. LinkedLists (или массивы с использованием chunking) помогают смягчить эту проблему, потому что пространство, в котором вы нуждаетесь, не должно быть смежным.

Поэтому, если ваше приложение не использует 2 ГБ ОЗУ, чем ваша проблема, скорее всего, фрагментация памяти, чем что-либо еще.

Windows 7, вероятно, управляет ОЗУ иначе, чем Windows XP, вероятно, почему вы не видите проблему там. Но проталкивайте больше данных, и я уверен, что вы столкнетесь с тем же вопросом.

Вы можете настроить perfmon для отслеживания/использования памяти журнала вашей системы и диспетчера задач для отслеживания вашего приложения.

Ответ 3

Я не знаю никаких жестких ограничений, установленных Windows или NETFX, но я очень подозрительно, что объем данных, возвращаемых из вашего С++-приложения, может быть совершенно произвольным, и это может привести к изменчивому поведению.

Я настоятельно рекомендую записать ваши данные журнала в файл в вашем родном компоненте, а затем прочитать файл из вашего управляемого кода. Таким образом, неважно, сколько данных записано, ваш управляемый код может анализировать его, не беспокоясь о том, чтобы выдуть кучу.