0

我知道 gcroot 用于保持对本机类中托管对象的引用,但是在非托管类函数中使用托管对象作为局部变量呢?编译器似乎没有对此产生错误,但它“正确”吗?会影响性能吗?

4

2 回答 2

0

托管对象、托管值类型 ( value struct, value class, enum class) 的值和托管引用类型 ( ref struct, ref class) 的句柄都可以在编译为 MSIL 的代码中使用。

并且编译为 MSIL 的代码可以是非托管对象的一部分(例如,标准 C++ 类型的虚拟成员函数可以编译为 MSIL,Visual C++ 编译器“It Just Works”技术将确保 v-表设置正确)。这在将标准 C++ 代码产生的事件和回调转发到托管 GUI 世界时非常有用。但是,如果您在托管代码(可能是 C#)中实现了要从 C++ 调用的算法,它也适用。

正如 Hans 所提到的,在 MSIL 和特定功能的机器代码生成之间切换会影响性能。但是,如果您处于本地管理的边界,那么编译到 MSIL 并使用“It Just Works”a/k/a“C++ interop”是迄今为止性能最高的替代方案。

于 2013-07-31T13:42:52.403 回答
0

没有本地托管对象之类的东西。所有托管对象都存储在堆上,需要让垃圾收集器完成其工作。您只能将引用作为局部变量。运行时的指针。

如果您使用 /clr 或有效编译该代码,则可以在非托管函数中使用托管对象引用#pragma managed。此类代码将被翻译成 IL 并在运行时即时编译,就像正常的托管代码一样。否则它将不具有托管代码的特征,没有验证,您将遭受所有正常的指针错误。是的,它会损害性能,因为这样的代码没有得到正常的优化器的喜爱。抖动中内置的优化器没有那么有效,因为它在时间限制下工作。

编译不带 /clr 选项的本机代码,或#pragma unmanaged在代码中使用以即时切换编译器。

于 2013-07-30T17:18:43.193 回答