What is the property or method (if any) that would provide the Win32 HANDLE from a .Net MemoryMappedFile?
I have unmanaged C++ code that reads from and writes to C-style FILEs, such as stdin and stdout. I want to create a MemoryMappedFile using MemoryMappedFile::CreateNew then get a Win32 HANDLE that can be converted to a FILE* for use in the unmanaged C++. I see MemoryMappedViewAccessor::SafeMemoryMappedViewHandle and SafeHandle and other possibilities but I don't find anything stating (or showing by example) that the handle can be used as a Win32 HANDLE in a C/C++ program. I am just not sure what specifically that provides the Win32 HANDLE. There are other possibilities, such as using all Windows API and no .Net but I am asking if this can be done using MemoryMappedFile, I am sure I can do it using all Windows API if it can't be done using MemoryMappedFile.
Update: The following is the code from @MichaelGunter converted to C++. See the comment from Hans Passant, he says this won't work and it does not. The handle returned from safeHandle->DangerousGetHandle() seems valid but when I call _open_osfhandle to convert the handle it fails.
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();
And this is the "Put" function.
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;
}
The MemoryMappedFile::SafeMemoryMappedFileHandle Property documentation says that I need security permission so I used the following in a few places.
[SecurityPermissionAttribute(SecurityAction::LinkDemand, UnmanagedCode = true)]