如何知道文件句柄号时打开文件?

时间:2010-08-25 02:45:41

标签: c# c++ interop

我使用FileStream在C#中打开一个文件,我用这一行得到了文件句柄号:

IntPtr file_handle = fs.SafeFileHandle.DangerousGetHandle();

现在我想将此句柄传递给C ++代码并使用此句柄值来访问该文件。这可能吗?如何用C ++中的文件句柄打开文件?

感谢。

更新

我使用C#将P / Invoke转换为C ++ Win32 DLL(而不是COM DLL)。我在C#中打开文件作为FileStream,并将句柄传递给C ++。这是我在C ++ DLL中的一些代码:

extern "C" __declspec(dllexport)void read_file(HANDLE file_handle)
{
    char buffer[64];
    ::printf("\nfile = %d\n",file_handle);

    if(::ReadFile(file_handle,buffer,32,NULL,NULL))
    {
        for(int i=0;i<32;i++)
            cout<<buffer[i]<<endl;
    }
    else
        cout<<"error"<<endl;
}

这是我的C#代码:

    [DllImport("...",EntryPoint = "read_file", CharSet = CharSet.Auto)]
    public static extern void read_file(IntPtr file_handle_arg);

但是我收到了这个错误:

Unhandled Exception: System.AccessViolationException: Attempted to read or write
 protected memory. This is often an indication that other memory is corrupt.

感谢。

4 个答案:

答案 0 :(得分:2)

你可以使用win32调用,就像文件流/文件构造器一样(通过p / invoke)。

.NET Reflector中打开它,看起来它正在使用此功能:

[DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
private static extern SafeFileHandle CreateFile(
  string lpFileName,
  int dwDesiredAccess,
  FileShare dwShareMode,
  SECURITY_ATTRIBUTES securityAttrs,
  FileMode dwCreationDisposition,
  int dwFlagsAndAttributes,
  IntPtr hTemplateFile);

这是官方参考:

http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx

这只是打开文件,但正如你所说的那样:

  

如何在C ++中仅使用文件句柄打开文件

如果您想阅读已打开的文件,可能会遇到更多麻烦。我不确定。您可以使用此功能:

[DllImport("kernel32.dll", SetLastError=true)]
internal static extern unsafe int ReadFile(
  SafeFileHandle handle,
  byte* bytes,
  int numBytesToRead,
  IntPtr numBytesRead_mustBeZero,
  NativeOverlapped* overlapped
);

http://msdn.microsoft.com/en-us/library/aa365467(v=VS.85).aspx

答案 1 :(得分:1)

这完全取决于 - 但你不太可能做到这一点。我假设你的C#代码和C ++代码在不同的进程中运行 - 如果你在同一个进程中,你应该只能IntPtr作为HANDLE进行编组。< / p>

问题是文件句柄特定于进程 - 您将无法在另一个进程中使用该句柄。

那就是说,你可能会更好:

  • 将文件名传递给C ++代码并在那里打开
  • 将实际包含在文件中的数据传递给C ++并在那里处理它。

答案 2 :(得分:0)

如果C ++代码是C ++ / CLI,那么根本不要理会句柄。只需将FileStream对象直接传递给您的C ++代码即可。

如果C ++是本机代码,那么您可以在通常使用Windows HANDLE值的任何位置使用文件句柄,例如ReadFileWriteFile。您不会使用句柄打开文件,因为它已经打开。如果您想要该句柄的另一个副本,或者您想要将句柄提供给另一个进程,请使用DuplicateHandle。如果您需要使用类似POSIX的函数(如_read_write),请调用_open_osfhandle以获取文件描述符。您可以使用_fdopen将文件描述符包装到C FILE*流中。

答案 3 :(得分:0)

原来标题并不是OP所追求的。

但如果有人真的需要这样做(例如:重新打开具有不同权限的文件),您可以使用GetFileInformationByHandle的组合来获取文件ID和OpenFileById。< / p>

FWIW。