У меня есть функция C ++ под названием innergetnum
что получает в качестве параметра float& num
Я пишу в управляемом C ++ функцию со следующим кодом:
void getnum(float% num)
{
innercppclass.innergetnum(num);
}
Это не работает, потому что он не может преобразовать num
в float&
Единственное решение, которое я нашел, это сделать дополнительную временную переменную float tmp
Передайте это innergetnum
а затем назначить его num
,
К сожалению, у меня есть много переменных ref, которые я хочу передать, и код выглядит уродливо, и я чувствую, что переменная temp — это хак.
Есть ли лучший способ решить это?
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;
}
}
Больше ничего вы не можете с этим поделать, это очень фундаментальное ограничение.
Других решений пока нет …