Лучший способ передачи по ссылке из C # в C ++? - PullRequest
1 голос
/ 03 августа 2009

У меня есть сторонняя коллекция .h файлов вместе с .lib файлами, которые идут вместе с ними. Я оборачиваю эти нативные файлы C ++ оболочкой C ++ / CLI и выполняю последние вызовы из C #. У меня есть проблема, когда я вызываю методы, которые ожидают передачи ссылки, когда значение не изменяется в моей оболочке, если я не изменю его явно.

Мой код оболочки C ++ / CLI в настоящее время выглядит следующим образом:

bool get_testInt16(int16% testInt16)
{
   int16* t = static_cast<int16*>(GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer());
   bool b = m_NativeCMTY_TestData->get_testInt16(*t);
   testInt16 = *t;
   return b;
};

И соответствующий нативный код C ++ выглядит так:

bool get_testInt16(int16 &testInt16);

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

Ответы [ 2 ]

4 голосов
/ 03 августа 2009

Можно сделать следующее:

bool get_testInt16(int16% testInt16)
{
   int16 t = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(t);
   testInt16 = t;
   return b;
};

Таким образом, вы просто создаете локальную собственную переменную и избегаете огромного приведения и .NET-указателей.

0 голосов
/ 03 августа 2009

по любой причине, вы не используете указатели закрепления вместо GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer()?

Также закрепление ссылочного значения, как это слишком поздно.

Если ссылка на значение стека не нужна, то если это ссылка на поле экземпляра, то вызывающий код должен действительно закрепить объект (хотя это грязная утечка неуправляемой семантики в управляемый код, которую он, по крайней мере, делает Поведение метода понятно.

Поскольку параметр ref настолько мал, имеет смысл просто полностью избежать пиннинга и создать временный в стеке, передать его неуправляемой функции, а затем записать обратно в оригинал.

bool get_testInt16(int16% testInt16)
{
   int16 temp = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(temp);
   testInt16 = temp;
   return b;
};
...