【问题标题】:Casting System::IO::FileStream^ to FILE*将 System::IO::FileStream^ 转换为 FILE*
【发布时间】:2014-09-30 06:18:37
【问题描述】:

我正在将大量代码从非托管 C++ 程序集重构为 C# 程序集。目前在两者之间有一个混合模式程序集,当然,混合了托管和非托管代码。我试图在依赖 FILE*s(如 stdio.h 中定义的)的非托管 C++ 中调用一个函数。此函数与一个更大的进程相关联,该进程尚不能重构为 C# 代码,但现在需要从托管代码中调用。

我已经搜索过,但找不到关于 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);
}

【问题讨论】:

  • 看起来是您的最佳选择。不过,似乎无法保证“OS 文件句柄”实际上是 FILE*。但如果是这样,它似乎不太可能改变。您可能必须通过输出流上的 GC.KeepAlive 来防止在本机代码中释放句柄。
  • 这真的有什么不同吗?如果数据很大,我预计开销会很小......
  • 不,FILE 是严格的 C 运行时抽象,与 Windows 句柄没有任何关系。您可以使用 _fdopen() 破解 32 位代码。
  • @MatsPetersson 问题不在于代码的速度,而在于代码的数量。可能有超过一千行(仅用于编写此特定数据文件)的 C++ 代码需要重构为 C#(从混合模式程序集转变为纯 C# 程序集)。编写文件太大而无法重构,但我正在重构类的其他部分,这意味着我需要能够从托管代码中调用本机的、非托管的 Write 方法。

标签: c++-cli managed


【解决方案1】:

你需要_open_osfhandle followed by _fdopen

铸造不是魔术。仅仅因为输入和输出类型适合您的情况并不意味着这些值是正确的。

【讨论】:

  • 我完全理解强制转换不是魔法,但我没有用 C++ 做过很多特定于 Windows 的编程。底层指针是否属于 FILE 类型是我的问题的一部分。感谢您的澄清!
  • 好吧,即使 HANDLE 做了 wrap FILE*,该指针也可能无法通过强制转换检索。
  • 关键是我什至没有意识到HANDLE 本身就是一种类型。
  • 即使使用有效的 HANDLE,_open_osfhandle 似乎总是返回 -1。 virtual void __clrcall Write(FileStream ^out) { if (!out->CanWrite) {} /* throw */ SafeFileHandle^ safeHandle = out->SafeFileHandle; if (safeHandle->IsInvalid) {} /* throw */ if (safeHandle->IsClosed) {} /* throw */ void *handle = safeHandle->DangerousGetHandle().ToPointer(); int fd = _open_osfhandle((intptr_t)handle, _O_APPEND | _O_RDONLY); if (fd == -1) {} /* throw */ FILE *fp = _fdopen(fd, "a+"); if (fp == NULL) {} /* throw */ Write(fp); System::GC::KeepAlive(out); }
猜你喜欢
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多