2016-03-04 99 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 <>。