Какой лимит памяти в WinXP при получении обратного вызова из C ++ DLL в C #? - PullRequest
10 голосов
/ 06 октября 2011

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

Основной поток состоит в том, что C # запускает операцию в 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, если буфер становится слишком большим, он падает. Я не уверен в точном размере, который вызывает это, но я установил ограничение в 8 МБ, и сбой исчез.

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

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

Ответы [ 3 ]

2 голосов
/ 18 марта 2012

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

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

1 голос
/ 14 октября 2011

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

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

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

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

0 голосов
/ 07 октября 2011

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

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

...