2012-11-01 82 views
0

我正在進行硬件測試。我們的測試框架是用C#編寫的,但我們使用本地dll與硬件進行通信。DllImport和返回參數

假設我們有一個C++方法:

unsigned char someMethod(unsigned long * nativeStatus) 

這又執行一個嵌入的命令,並返回一個狀態命令完成時。

要使用它,我們創建一個包裝

[DllImport(@"native.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] 
internal static extern Byte someMethod(ref UInt32 managedStatus) 

這工作得很好。但有一種情況是someMethod調用並不實際執行一個命令,而只是將它添加到一個序列中。然後可以通過發送一個特殊命令ExecuteSequence來執行該序列。在序列正在執行時,C++代碼通過將數據複製到nativeStatus指針所指的內存中來更新nativeStatus。隨着順序完成ExecuteSequence方法返回。此時我確信所有數據(本例中的nativeStatus)都已更新。我的managedStatus也會正確更新嗎?我聽說在這種情況下,managedStatusnativeStatus沒有指向相同的內存。在呼叫完成後,Marshaler僅返回nativeState的副本。如果不是解決方案是什麼?我是否需要使用unsave關鍵字並將我的代碼創建並在fixed{}塊中執行序列?

[DllImport(@"native.dll", CharSet=CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] 
internal static unsave extern Byte someMethod(UInt32 * managedStatus) 
+0

你是說'someMethod'有可能kcik關閉後臺運行,而您希望它運行訪問狀態?或者'someMethod'永遠是一個阻塞的調用,在其工作過程中,在退出時設置一個狀態碼? – tcarvin

回答

0

所以你需要的是一個可變的位置,它不會在一個時間範圍內變化。

是的,你可以使用fixed{}
或者,您可以固定變量:

private uint g_Pinnable = 0; 

... 

var gc = System.Runtime.InteropServices.GCHandle.Alloc(g_Pinnable, System.Runtime.InteropServices.GCHandleType.Pinned); 

try 
{ 
    // Pass 'ref g_Pinnable' to API 
    // Then execute the sequence. 
} 
finally 
{ 
    gc.Free(); // Reference to g_Pinnable may be invalid after this point 
}