2016-03-04 91 views
2

我有一个C++/CLI方法,ManagedMethod,与一个输出参数,将通过一个本地方法这样进行修改:的n值已被修改,我期望C++/CLI方法调用本地方法修改int - 需要pin_ptr?

// file: test.cpp 

#pragma unmanaged 
void NativeMethod(int& n) 
{ 
    n = 123; 
} 
#pragma managed 

void ManagedMethod([System::Runtime::InteropServices::Out] int% n) 
{ 
    pin_ptr<int> pinned = &n; 
    NativeMethod(*pinned); 
} 

void main() 
{ 
    int n = 0; 
    ManagedMethod(n); 
    // n is now modified 
} 

一旦ManagedMethod回报。到目前为止,我已经能够编译的唯一方法是在ManagedMethod中使用pin_ptr,所以实际上只有这样做才是正确的方法?还是有一种更优雅的方式将n传递给NativeMethod

回答

2

是的,这是正确的做法。在CLR中非常高度优化,变量获取[pinned]属性,因此CLR知道它存储了一个指向不应该被移动的对象的内部指针。与GCHandle :: Alloc()不同,pin_ptr <>可以在不创建另一个句柄的情况下执行此操作。在表中报告,当编译该方法时产生抖动,GC使用该表来知道在哪里查找对象根。

在NativeMethod()运行的同一时间发生垃圾收集时,这只会非常重要。实践中不经常发生,你必须在程序中使用线程。因人而异。

还有另一种方式做到这一点,并不需要寄托,但需要更多的一丁点儿的机器代码:

void ManagedMethod(int% n) 
{ 
    int copy = n; 
    NativeMethod(copy); 
    n = copy; 
} 

哪些工作,因为局部变量已经栈存储,因此不会被移动垃圾收集器。没有赢得风格的优雅点,但我通常使用自己,估计钉住的副作用并不容易。但是,真的,不要害怕pin_ptr <>。