假设我写了以下代码:
public ref class Data
{
public:
Data()
{
}
Int32 Age;
Int32 year;
};
public void Test()
{
int age = 30;
Int32 year = 2010;
int* pAge = &age;
int* pYear = &year;
Data^ data = gcnew Data();
int* pDataYear = &data->Year; // pData is interior pointer and the compiler will throw error
}
如果编译程序,编译器将抛出错误:
错误C2440:'初始化':无法从'cli :: interior_ptr'转换为'int *'
所以我了解到“& data-> Year”是一种内部指针
更新:我尝试使用“&(data-> Year)”,同样的错误。
但是pAge和pYear怎么样? 它们是原生指针,内部指针还是固定指针??
如果我想在以下原生函数中使用它们:
void ChangeNumber(int* pNum);
通过pAge或pYear是否安全?
答案 0 :(得分:2)
他们(pAge
和pYear
)是本机指针,将它们传递给本机函数是安全的。堆栈变量(具有自动存储生命周期的本地)不受垃圾收集器的重新排列,因此不需要固定。
将托管数据复制到堆栈,然后将其传递给本机函数,在许多情况下解决了gc-moving-managed-data-around问题(当然,不要将它与期望原始变量的回调一起使用)在您的包装器有机会复制该值之前进行更新。
要获取托管数据的本机指针,必须使用固定指针。这可能比将值复制到堆栈的方法要慢,因此将其用于较大的值,或者当您确实需要函数直接对同一个变量进行操作时(例如,该变量用于回调或多线程)。 / p>
类似的东西:
pin_ptr<int> p = &mgd_obj.field;