Как открыть файл, когда известен номер дескриптора файла? - PullRequest
0 голосов
/ 25 августа 2010

Я открываю файл в C # с FileStream, и я получил номер дескриптора файла с этой строкой:

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 ]

2 голосов
/ 25 августа 2010

Вы можете использовать вызовы 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 голос
/ 25 августа 2010

Это полностью зависит - но вряд ли вы сможете это сделать.Я предполагаю, что ваш код C # и код C ++ выполняются в разных процессах - если вы находитесь в одном и том же процессе, вы можете просто маршалировать через IntPtr как HANDLE.

Проблема в том, что файловые дескрипторы специфичны для процесса - вы не сможете использовать этот дескриптор в другом процессе.

Тем не менее, вам, вероятно, лучше:

  • Передача имени файла в код C ++ и его открытие там
  • Передача фактически содержащихся в нем данных в C ++ и их обработка там.
0 голосов
/ 04 июня 2018

Оказывается, заголовок на самом деле не тот, что был после ОП.

Но если кому-то действительно нужно это сделать (например, открыть файл с другими разрешениями), вы, вероятно, можете использоватькомбинация GetFileInformationByHandle для получения идентификатора файла и OpenFileById .

FWIW.

0 голосов
/ 25 августа 2010

Если код C ++ - C ++ / CLI, то вообще не беспокойтесь о дескрипторе.Просто передайте объект FileStream непосредственно в код C ++.

Если C ++ является собственным кодом, то вы можете использовать дескриптор файла везде, где обычно используете значение Windows HANDLE для файлов, напримерReadFile и WriteFile.Вы не будете использовать дескриптор для открытия файла, потому что он уже открыт.Если вам нужна другая копия дескриптора или если вы хотите передать дескриптор другому процессу, используйте DuplicateHandle.Если вам нужно значение с POSIX-подобными функциями, такими как _read и _write, то вызовите _open_osfhandle, чтобы получить дескриптор файла.Вы можете поместить дескриптор файла в поток C FILE* с помощью _fdopen.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...