我使用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.
感谢。
答案 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>
问题是文件句柄特定于进程 - 您将无法在另一个进程中使用该句柄。
那就是说,你可能会更好:
答案 2 :(得分:0)
如果C ++代码是C ++ / CLI,那么根本不要理会句柄。只需将FileStream
对象直接传递给您的C ++代码即可。
如果C ++是本机代码,那么您可以在通常使用Windows HANDLE
值的任何位置使用文件句柄,例如ReadFile
和WriteFile
。您不会使用句柄打开文件,因为它已经打开。如果您想要该句柄的另一个副本,或者您想要将句柄提供给另一个进程,请使用DuplicateHandle
。如果您需要使用类似POSIX的函数(如_read
和_write
),请调用_open_osfhandle
以获取文件描述符。您可以使用_fdopen
将文件描述符包装到C FILE*
流中。
答案 3 :(得分:0)
原来标题并不是OP所追求的。
但如果有人真的需要这样做(例如:重新打开具有不同权限的文件),您可以使用GetFileInformationByHandle的组合来获取文件ID和OpenFileById。< / p>
FWIW。