Распределители памяти для нативной библиотеки C ++, которая будет использоваться C # - PullRequest
0 голосов
/ 31 января 2010

Я пишу некоторый нативный код C ++, который необходимо вызывать из C # (и я не могу заменить нативный код C ++ кодом C #).

Я обнаружил повреждения памяти при выделении / освобождении некоторой памяти в собственном коде C ++ с использованием malloc / free. Затем я использовал LocalAlloc / LocalFree и HeapAlloc / HeapFree и имел те же проблемы.

Распределения / освобождения кажутся правильными, и они происходят в отдельном потоке, созданном собственным кодом.

Мне было интересно, какую стратегию размещения лучше использовать в нативной библиотеке C ++, называемой C #

РЕДАКТИРОВАТЬ: обнаружил проблему: проблема не в коде выделения / освобождения, а в некоторой памяти, записываемой после освобождения.

Ответы [ 3 ]

1 голос
/ 31 января 2010

Пока сторона кода C # использует переключатель компилятора /unsafe и ключевое слово fixed, используемое для хранения буфера данных, я думаю, что вы должны быть в порядке.

Что касается вопроса о выделении памяти, то, возможно, проблема связана не с кодом выделения памяти C ++, а с тем, как код C ++ взаимодействует с драйвером ... возможно, с использованием VirtualAlloc / VirtualFree пара согласно MSDN документам ...

Редактировать: Когда вы пытаетесь выделить буфер для хранения данных со стороны C ++ после взаимодействия с драйвером ... возможно, состояние гонки или задержка прерывания вызывают повреждение памяти ... просто мысль ...

Надеюсь, это поможет, С наилучшими пожеланиями, Том.

1 голос
/ 31 января 2010

В вашем вопросе отсутствуют важные детали, совершенно не ясно, нужно ли освобождать память, выделенную кодом C ++, на стороне C #. Обычно это делается автоматически, скажем, с помощью маршаллера P / Invoke или уровня взаимодействия COM в CLR. Или это можно сделать вручную, объявив аргумент метода как IntPtr, а затем использовать класс Marshal.

Если это делается автоматически, вы должны использовать распределитель памяти COM, CoTaskMemAlloc (). Если вы выполняете маршалинг самостоятельно, вы также можете использовать GlobalAlloc (), выпустите на стороне C # с Marshal.FreeHGlobal (). Использование GlobalAlloc () не дает никаких преимуществ, вы также можете использовать CoTaskMemAlloc () и выпустить его вместе с Marshal.FreeCoTaskMem ().

Но ты должен был заметить это сам. Выделение с помощью malloc () или HeapAlloc () на стороне C ++ вызывает утечки вместо повреждения, если управляемый код освобождает память. Vista и Win7 имеют гораздо более строгий менеджер кучи, он завершает программу, если замечает плохой выпуск.

Мне кажется, что в вашем коде C ++ есть простое повреждение кучи. Это самая распространенная проблема неуправляемого программирования на C ++, переполнение конца буфера, запись в освобожденную память, неправильные значения указателя. Способ избавиться от подобных ошибок - тщательный анализ кода и использование распределителя отладки, такого как предоставленный <crtdbg.h>. Удачи с этим.

0 голосов
/ 31 января 2010

Рекомендовать комплект разработки драйверов для Windows против использования C ++ для драйверов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...