2014-09-30 60 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