2012-08-09 21 views
0

我需要一個C#接口通過CLI方言調用一些本地C++代碼。 C#接口在所需參數前面使用out屬性說明符。這轉換爲C++/CLI中的跟蹤引用。C++/CLI從跟蹤引用(本地)引用 - 包裝

我有以下的簽名和體(這是另一個調用本地方法做的工作)的方法:

virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed 
{ 
    mRenderWindow->getMetrics(width, height, colourDepth, left, top); 
} 

現在的代碼不會因爲一些編譯時錯誤編譯(全部爲與not being able to convert parameter 1 from 'unsigned int' to 'unsigned int &'有關)。

作爲一名謙虛的C++程序員,對我來說,CLI看起來像荷蘭人,對德語的人來說。可以做些什麼來使這個包裝在CLI中正常工作?

回答

1

就像是在一個已刪除的答案還建議,我做了明顯的和使用的局部變量,以繞過相關的值:

virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed 
     { 
      unsigned int w = width, h = height, c = colourDepth; 
      int l = left, t = top; 
      mRenderWindow->getMetrics(w, h, c, l, t); 
      width = w; height = h; colourDepth = c; left = l; top = t; 
     } 

這是一個有點明顯,因爲跟蹤基準的比較直觀的機制:它們受垃圾回收器工作的影響,並不像正常的&引用那樣靜態/常量,因爲它們很容易被放在內存中的其他位置。因此,這是解決問題的唯一可靠方法。感謝最初的答覆。

0

如果你的參數使用 '出' C#的一面,你需要定義你的C++/CLI參數如下:[Out] unsigned int ^%width

下面是一個例子:

virtual void __clrcall GetMetrics([Out] unsigned int ^%width) 
{ 
    width = gcnew UInt32(42); 
} 

然後在你的C#的一面,你會得到42:

ValueType vt; 
var res = cppClass.GetMetrics(out vt); 
//vt == 42 

爲了使用[OUT]參數的C++/CLI側則需要包括:

using namespace System::Runtime::InteropServices; 

希望這有助於!

+0

感謝您的回覆,奇怪的是,它沒有編譯我第一次嘗試它(現在不是!編譯器錯誤)。是的,在C#界面中,參考參數的前面有_out_屬性。但是,這個解決方案只是把'%'跟蹤的ref操作符放在它們前面(這也是編譯器建議的做法 - 雖然我嘗試了System :: Runtime :: InteropServices :: Out屬性。問題是我需要將'width'傳遞給一個普通的本地C++例程,這是行不通的(請參閱我的關於轉換失敗的錯誤信息)乾杯! – teodron 2012-08-10 16:03:59

+1

拳擊價值類型值是一個非常糟糕的想法,它也不能解決OP的問題 – 2012-08-10 16:53:40

+0

回答更新(感謝@ HansPassant的建議和初步解釋)+1 – teodron 2012-08-13 13:17:37

0

您可以使用pin_ptr,以便在本地代碼更改時'寬度'不會移動。託管端受到pin_ptr的影響,但我認爲如果您希望本地代碼直接訪問而不用'w',則可以解決這個問題。

virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed 
     { 
      pin_ptr<unsigned int> pw = &width; //do the same for height 
      mRenderWindow->getMetrics(*pw, h, c, l, t); 
     }