我知道gcroot用于保存本机类中托管对象的引用,但是在非托管类函数中使用托管对象作为 local 变量呢? 编译器似乎没有在此生成错误,但是它是否正确" ?这会影响性能吗?
答案 0 :(得分:0)
没有本地托管对象这样的东西。所有托管对象都存储在堆上,这是让垃圾收集器完成其工作所必需的。您只能将引用作为本地变量。运行时的指针。
如果使用/ clr或#pragma managed
生成有效的代码,则可以在非托管函数中使用托管对象引用。这些代码将被转换为IL并在运行时即时编译,就像普通的托管代码一样。它不会具有托管代码的特性,没有验证,你将遭受所有正常的指针错误。是的,它可能会损害性能,因为这样的代码并没有得到普通优化器的喜爱。抖动内置的优化器效率不高,因为它在时间限制下工作。
编译没有/ clr选项的本机代码或在代码中使用#pragma unmanaged
来动态切换编译器。
答案 1 :(得分:0)
托管对象,托管值类型的值(value struct
,value class
,enum class
)和托管参考类型的处理(ref struct
,ref class
)可以在编译为MSIL的代码中使用。
编译为MSIL的代码可以是非托管对象的一部分(例如,标准C ++类型的虚拟成员函数可以编译为MSIL,而Visual C ++编译器“It Just Works”技术将确保v-table设置正确)。将标准C ++代码生成的事件和回调转发到托管GUI世界时,这非常有用。但是,如果您要在托管代码(可能是C#)中实现要从C ++调用的算法,它也适用。
正如汉斯所提到的,在特定功能的MSIL和机器代码生成之间切换会产生性能影响。但是如果你坐在本地管理的边界上,那么编译成MSIL并使用“It Just Works”a / k / a“C ++ interop”是迄今为止最高性能的替代方案。