c # — преобразование .net-ссылки в c ++-ссылку

У меня есть функция C ++ под названием innergetnum что получает в качестве параметра float& num

Я пишу в управляемом C ++ функцию со следующим кодом:

void getnum(float% num)
{
innercppclass.innergetnum(num);
}

Это не работает, потому что он не может преобразовать num в float&

Единственное решение, которое я нашел, это сделать дополнительную временную переменную float tmpПередайте это innergetnum а затем назначить его num,

К сожалению, у меня есть много переменных ref, которые я хочу передать, и код выглядит уродливо, и я чувствую, что переменная temp — это хак.

Есть ли лучший способ решить это?

1

Решение

error C2664: 'innercppclass::getnum' : cannot convert parameter 1 from 'float' to 'float &'
An object from the gc heap (a dereferenced gc pointer) cannot be converted to a native reference

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

Аргумент float% управляемой функции может быть внутренним указателем на управляемый объект, подобно полю класса ref. Поплавок& ссылка будет необработанным неуправляемым указателем во время выполнения, указывающим на значение с плавающей точкой. Что позволяет вызываемому обновить значение. Оба являются просто указателями во время выполнения, единственное отличие состоит в том, что сборщик мусора может видеть внутренний указатель, но не неуправляемый указатель. Джиттер говорит ему, где искать управляемый указатель, такой помощи для нативной функции C ++ нет, поскольку она не была объединена.

Таким образом, назначение неуправляемого указателя со значением внутреннего указателя будет возможно. Однако что-то очень неприятное случается, когда сборщик мусора работает во время работы нативного кода. Обратите внимание, что сборщик мусора может возникать, когда другие потоки в программе выделяют память. GC делает одну важную вещь компактный куча, он перемещает управляемые объекты как часть коллекции. Очень желательная черта, она избавляет от дыр в куче и делает управляемый код быстрым, улучшая локальность ссылок. Проблема в том, что нативный код содержит указатель на то место, где он находился до перемещения. И если он пишет через указатель, обновляя значение с плавающей точкой, он будет продажный куча GC.

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

Таким образом, компилятор жалуется, что он не может сгенерировать код, который рано или поздно (обычно позже) не приведет к сбою вашей программы с совершенно не диагностируемым повреждением кучи. Вы уже нашли обходной путь, вам нужно сгенерировать указатель из места хранения, которое не куча GC. Стек в порядке, локальные переменные никогда не перемещаются:

void Managed::getnum(float% num) {
float temp;
innercppclass::getnum(temp);
num = temp;
}

Иначе, код, который вы бы написали, когда вы превращаете void getnum (float%) в float getnum (). Или, как правило, в управляемом коде, получатель свойства:

property float num {
float get() {
float temp;
innercppclass::getnum(temp);
return temp;
}
}

Больше ничего вы не можете с этим поделать, это очень фундаментальное ограничение.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]