2017-04-05 9 views
0

.Net MemoryMappedFileからWin32 HANDLEを提供するプロパティまたはメソッド(存在する場合)とは何ですか?MemoryMappedFileからWin32 HANDLEを取得します。

私は、Cスタイルのファイル(stdinやstdoutなど)との間で読み書きを行うアンマネージドC++コードを用意しています。 MemoryMappedFile :: CreateNewを使用してMemoryMappedFileを作成し、Unmanaged C++で使用するFILE *に変換できるWin32 HANDLEを取得します。私はMemoryMappedViewAccessor :: SafeMemoryMappedViewHandleとSafeHandleなどの可能性を参照していますが、ハンドルがC/C++プログラムでWin32ハンドルとして使用できることを示す(または例で示す)ものは見つかりません。私はWin32のハンドルを提供するものが何であるか分かりません。他の可能性があります。たとえば、すべてのWindows APIとno .Netを使用していますが、MemoryMappedFileを使用してこれを行うことができるかどうかを確認するために、MemoryMappedFileを使用できない場合はすべてのWindows APIを使用できます。

更新:以下は、@MichaelGunterのコードをC++に変換したものです。ハンス・パサントからのコメントを見てください。彼はこれはうまくいかないと答えています。 safeHandle-> DangerousGetHandle()から返されたハンドルは有効と思われますが、_open_osfhandleを呼び出してハンドルを変換すると失敗します。

MemoryMappedFile^ mmf = nullptr; 
try { mmf = MemoryMappedFile::CreateNew("testmap", 10000, MemoryMappedFileAccess::ReadWrite); } 
catch (Object^ ex) 
{ 
    // show error 
    return; 
} 
SafeMemoryMappedFileHandle^ safeHandle = mmf->SafeMemoryMappedFileHandle; 
bool success = false; 
safeHandle->DangerousAddRef(success); 
if (!success) 
{ 
    // show error 
    return; 
} 
IntPtr handle = safeHandle->DangerousGetHandle(); 
if (safeHandle->IsInvalid) 
{ 
    // show error 
    return; 
} 
pin_ptr<const wchar_t> wchstr = PtrToStringChars(Message); 
if (!Put((intptr_t)handle, const_cast<wchar_t*>(wchstr))) 
{ 
    // show error 
    return; 
} 
safeHandle->DangerousRelease(); 

これは「プット」機能です。

BOOL Put(intptr_t h, wchar_t* Message) { 
    int fd = _open_osfhandle(h, 0); 
    if (fd < 1) 
     return FALSE; 
    FILE * fp = _wfdopen(fd, L"w"); 
    fputws(Message, fp); 
    return TRUE; 
} 

MemoryMappedFile::SafeMemoryMappedFileHandle Property ドキュメントは、私はので、私はいくつかの場所に次のように使用されるセキュリティ許可が必要であることを述べています。メモリマップトファイルを考えると

[SecurityPermissionAttribute(SecurityAction::LinkDemand, UnmanagedCode = true)] 
+0

これを行う直接的な方法はありません。これは助けになるかもしれません:http://stackoverflow.com/questions/5193579/how-make-file-from-handle-in-winapi –

+0

@ダン、はい、ありがとうございます。私はそれについて知っていた。私は私の質問でハンドルをしている必要があります。私は混乱していることをお詫び申し上げます。私はFILE *の代わりにハンドルを言うように私の質問を更新しようとします。 – user34660

+0

このようなハンドルをFILE *に変換することはできません。 XY質問。 –

答えて

0

MemoryMappedFile mmf = ...; 

は、 "安全" のハンドルを取得します。ハンドルが使用されている限り、この安全ハンドルを保管してください。

SafeMemoryMappedFileHandle safeHandle = mmf.SafeMemoryMappedFileHandle; 

それは埋め立てていないように、ハンドルへの参照を追加します。

bool success = false; 
safeHandle.DangerousAddRef(ref success); 
if (!success) 
    throw new InvalidOperationException("Failed to addref handle."); 

は、生のハンドルを取得します:

IntPtr handle = safeHandle.DangerousGetHandle(); 

あなたは生のハンドルが完了したら、リリース安全なハンドル:

safeHandle.DangerousRelease(); 
+0

コードをC++に変換するための1つの注意は、名前空間を使用してMicrosoft :: Win32 :: SafeHandles;を追加することです。 – user34660

+0

コードをC++に変換して質問を更新しました。ハンス・パッセントは、それはうまくいかないと言いますが、それを働かせることができれば、それは素晴らしいことでしょう。 – user34660

+0

FILE *ではうまくいきません。 :) –

0

メモリマップされたファイルオブジェクトへのハンドルを得ることはできますが(Michaelの答えで説明した通りです)、このハンドルを__open_osfhandleに渡すことはできません。メモリマップされたファイルオブジェクトをファイルオブジェクトのように使うことができないからです。つまり、ハンドルの読み書きはできません。 のみを使用して、ファイルマッピングオブジェクトのビューをメモリにマップすることができます。

Win32 APIを直接使用しても違いはありません。ファイルマッピングオブジェクトは、単にあなたが探している機能を提供しません。

パイプオブジェクトを使用するようにしてください。パイプをファイルとして扱うことができます。但し、ファイルポインタを移動しようとしない場合に限ります。そして、MicrosoftのCランタイムは、ファイルハンドルの代わりにパイプハンドルを受け入れることができると信じていますが、これはドキュメントには記載されていません。

Pipe Operations in the .NET Frameworkを参照してください。

+0

....または、もちろん、実際のファイルを使用することができます。 –

+0

パイプはWin32 APIを使用します。私は[リダイレクトされた入力と出力を持つ子プロセスを作成する](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v = vs.85).aspx)に精通しています。数年前、私は.Netのパイプの実装を有効にしようとしましたが、できませんでした。私は、.NetのパイプにWCFを使う方が良いと思います。パイプを使用する場合は、Windows APIを通してパイプを直接使用することをお勧めします。 – user34660

+1

はい、C++で書いているので、コンテキストに応じてWin32 APIもおそらく私の好みになるでしょう。私は、あなたがCreateFileMappingではなく.NETのMemoryMappedFileクラスを使用していたので、.NETパイプクラスも好むだろうと思っていましたが、実際には違いはありません。 –

関連する問題