2014-09-30 62 views
0

我正在將大量代碼從非託管C++程序集重構到C#程序集。目前有兩種混合模式彙編,當然是混合使用託管代碼和非託管代碼。有一個函數我試圖調用非託管C++,它依賴於FILE * s(在stdio.h中定義)。這個函數綁定到一個更大的過程中,這個過程不能被重構成C#代碼,但是需要從託管代碼中調用哪個現在Casting System :: IO :: FileStream ^到FILE *

我已經搜索,但無法找到System :: IO :: FileStream類使用什麼樣的基礎系統指針的明確答案。這只是應用在FILE *之上嗎?或者有其他方法可以將FileStream ^轉換爲FILE *嗎?我發現FileStream :: SafeFileHandle,我可以在其上調用DangerousGetHandle()。ToPointer()來獲得一個本地void *,但我只是想確定如果我把這個文件轉換成FILE *,我正在做的是正確的事情...?

void Write(FILE *out) 
{ 
    Data->Write(out); // huge bulk of code, writing the data 
} 

virtual void __clrcall Write(System::IO::FileStream ^out) 
{ 
    // is this right?? 
    FILE *pout = (FILE*)out->SafeFileHandle->DangerousGetHandle().ToPointer(); 
    Write(pout); 
} 
+0

看起來像你最好的選擇。似乎沒有任何保證,但「操作系統文件句柄」實際上是一個文件*。但如果是這樣,似乎不太可能改變。您可能不得不通過GC.KeepAlive在本地代碼中釋放句柄。 – heinrichj 2014-09-30 06:52:07

+0

這是否有任何區別?如果數據很大,我預計開銷很小...... – 2014-09-30 07:01:33

+2

不,FILE是一個嚴格的C運行時抽象,與Windows句柄無關。您可以使用_fdopen()對32位代碼進行破解。 – 2014-09-30 09:40:15

回答

1

您需要_open_osfhandle followed by _fdopen

鑄造不是魔術。僅僅因爲輸入和類型輸出適合您的情況並不意味着這些值。

+0

我完全理解鑄造不是魔術,但我沒有在C++中完成很多Windows特定的編程。底層指針是否是FILE類型是我的問題的一部分。感謝您的澄清! – 2014-10-01 02:30:14

+0

那麼,即使'HANDLE'做了_wrap_一個'FILE *',那麼這個指針可能不會被演員檢索到。 – MSalters 2014-10-01 07:18:02

+0

重要的是,我甚至沒有意識到「HANDLE」本身就是一種類型。 – 2014-10-01 07:23:42