我有一个名为innergetnum
的c ++函数,它作为参数float& num
我使用以下代码在托管c ++中编写函数:
void getnum(float% num)
{
innercppclass.innergetnum(num);
}
它不起作用,因为他无法将num
转换为float&
我找到的唯一解决方案是制作额外的临时变量float tmp
,将其传递给innergetnum
,然后将其分配给num
。
不幸的是我有很多我希望传递的ref变量,代码看起来很难看,我觉得temp变量是一个hack。
有没有更好的方法来解决它?
答案 0 :(得分:3)
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 ++函数的帮助,因为它没有被jitted。
因此,可以使用内部指针值分配非托管指针。但是,当本机代码运行时垃圾收集器运行时会发生非常讨厌的事情。请注意,当程序中的其他线程分配内存时,可能会发生GC。 GC做的一件重要事情是 compact 堆,它将托管对象作为集合的一部分移动。它是一个非常理想的特性,它可以消除堆中的漏洞,并通过改进引用的局部性来快速管理代码。麻烦的是,本机代码持有一个指针,指向浮动在移动之前的位置。如果它通过指针写入,更新浮点值,它将损坏 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;
}
}
你无能为力,这是一个非常基本的限制。