2D-массивы кросс-языков C ++ и C # - PullRequest
0 голосов
/ 14 ноября 2010

Если я хочу вызвать внешнюю функцию C ++, которая возвращает двумерный массив, с какими проблемами я могу столкнуться? Например, если я объявлю двумерный массив внутри функции C ++ и инициализирую размер массива внутри функции C ++, как автоматический. Сборщик мусора .Net справится с этим? Должен ли я дать ему функцию, которая выполняет сборку мусора, и если да, то как мне вызвать его из программы на C #?

Ответы [ 3 ]

2 голосов
/ 14 ноября 2010

Если функция не возвращает вектор или векторы, это точная та же проблема и в C ++.Это проблема управления памятью, вызывающая функция не имеет хорошего способа освободить память массива, она не знает размеров массива и того, какой распределитель использовался.В этом отношении даже итерация массива опасна.Проблема, которую вы не можете исправить в C ++, также не может быть исправлена ​​в управляемом взаимодействии.

И вы решаете ее так же, вы позволяете вызывающей стороне предоставлять массив, который будет заполнен вызываемой стороной.

Обратите внимание, что управляемые массивы не имеют этой проблемы, они являются классами, как вектор <>.Возвращение управляемого массива из функции не является проблемой.C ++ / CLI может сделать это, стандартное решение для сложных проблем взаимодействия.SAFEARRAY также является решением, расскажите маршаллеру P / Invoke о них с [MarshalAs] в управляемой декларации.

0 голосов
/ 14 ноября 2010

Я знаю, что для простых типов, таких как строка, взаимодействие создаст копию неуправляемого объекта и отправит его обратно вызывающей стороне.В этот момент CLR попытается очистить память с помощью вызова CoTaskMemFree().Успешно это или нет, зависит от того, как была выделена память.Если вы можете, используйте CoTaskMemAlloc() для выделения памяти, что позволит успешно выполнить вызов CoTaskMemFree ().

Я читал, что сбой при освобождении памяти приведет к утечке в XP, но вызовет исключение в Vista и Win7 ... не может говорить о достоверности этого.

Для более сложных типов, таких как массив, я не уверен, верно ли это.Тем не менее, отличный метод для освобождения памяти есть в статье здесь .

Суть в том, чтобы передать данные обратно как IntPtr, а затем предоставить метод из вызываемой библиотеки DLL, называемой FreeMemory(), который берет IntPtr и освобождает выделенную там память.

HTH,Джеймс

0 голосов
/ 14 ноября 2010

как автоматический сборщик мусора .Net справится с этим?

Не будет, это не имеет никакого отношения к памяти, выделенной нативными приложениями.Вы можете вернуть копию массива в модуль C #, и это решит эту проблему.Если он очень большой и это будет проблемой ... ну, может, у кого-то есть лучшее предложение, потому что мне еще не приходилось переходить этот мост =).Вы, вероятно, разместите и уничтожите его в коде C ++ и вернете указатель на модуль C #.Осторожнее с этим, и, как я уже сказал, мне не нужно было ничего такого делать.

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