C ++ DLL падает при вызове из управляемого кода - PullRequest
2 голосов
/ 16 августа 2011

есть WinForms-приложение, написанное на C # с использованием .NET Framework 3.5. Это приложение использует C ++ Dll, который импортируется с использованием следующего объявления:

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

Этот метод импортирует данные из заданного ODBC-DSN с использованием базы данных SQL Server. Вызывает сбой, когда в базе данных слишком много данных. Поставщик этой внешней библиотеки DLL сказал, что это происходит потому, что библиотека DLL не может получить больший размер кучи, и мое приложение должно предоставить больше памяти кучи.

Как я мог решить эту проблему? Насколько я знаю, единственная возможность исключить компонент из автоматической сборки мусора - это небезопасное ключевое слово, которое я уже использовал. Любая идея будет оценена.

Заранее спасибо

Martin

Ответы [ 3 ]

0 голосов
/ 16 августа 2011

Это похоже на проблему с библиотекой поставщика, а не с вашим кодом.

Управляемая и неуправляемая память должны рассматриваться как полностью разделенные. Управляемая память - это, как правило, память, выделенная для сборки мусора. куча, а неуправляемая память - это что-то еще: пул памяти ANSI C выделяется через malloc (3), пользовательские пулы памяти и выделенные мусором кучи вне контроля реализации CLI ...

Обратите внимание, что приведенная выше цитата взята из Mono документации , но я считаю (если я не ошибаюсь) то же самое верно для .NET в целом. Если данные загружаются во внутренние структуры данных DLL, они должны выделить свою собственную память. Если вы предоставляете буфер, который будет заполнен данными, то он будет заполнен только тем количеством данных, которое вы выделили для буфера (и закреплено перед маршалингом). Так, где данные загружаются?

0 голосов
/ 16 августа 2011

Я сомневаюсь, что это относится к .NET, управляемой памяти, сборке мусора и т. Д. Это нативная DLL, поэтому она использует обычную неуправляемую память. Конечно, среда выполнения .NET также будет использовать свою долю памяти, но нативное приложение, использующее DLL, будет делать то же самое.

Если вы работаете в 32-битном процессе, общий размер кучи для .NET и неуправляемого кода может быть ограничен 1,5 ГБ. Трудно сказать без дополнительной информации, но вы, возможно, достигли этого предела.

Таким образом, один из вариантов - спросить вашего поставщика, есть ли у него 64-битная версия библиотеки и перейти на 64-процесс. В 64-битном процессе память практически не ограничена (согласно сегодняшнему стандарту).

0 голосов
/ 16 августа 2011

Вы не можете увеличить размер кучи в .NET.Вы можете создать в c / c ++ EXE-файл, который ваше приложение .NET вызывает с помощью Process.Start.Ваш c / c ++ EXE просто вызовет функцию DLL и вернет результат (или, если у вас более одной функции, он может принять параметр командной строки).Если вам не нужен отдельный EXE-файл, попробуйте использовать RunDll32.

...