使用内存映射文件 (IOException) 进行进程间通信(C++ 到 C#)
有两个进程:一个用 C++ 编写,另一个用 C# 编写。
简单地说,C++进程将创建一个名为“test.dat”的文件,将该文件映射到其内存,并继续在其上写入。
另一方面,只要内存发生更改,C# 进程就会打开文件并进行读取。
问题是在 C# 端,它不允许我打开该文件。 (IOException 表示另一个进程正在使用中”
这是我测试过的内容。
//C++
// Test create & open
void CTestDlg::OnBnClickedBtn1()
{
WCHAR wcsDebug[1024];
HANDLE hFile, hMapFile;
UINT size = sizeof(syncData);
hFile = CreateFile(L"C:\\Users\\test\\Documents\\2134\\test.dat", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, NULL);
if (hMapFile)
{
g_pb = (BYTE*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
}
}
}
// Test Writing
void CLibTestDlg::OnBnClickedBtn2()
{
WCHAR sz[] = L"C:\\Users\\test\\Documents\\2134\\";
WCHAR wcsFilePath[MAX_PATH];
CString str;
GetDlgItemText(IDC_EDIT_FID, str);
if (str != L"\0")
{
swprintf_s(wcsFilePath, _countof(wcsFilePath), L"%s%s", sz, str.GetBuffer());
if (g_pb)
{
syncData sd;
sd.dwCurrent = nCurr;
sd.dwTotal = 15;
sd.eSyncType = TYPE_DOWNLOAD;
StringCchCopy(sd.wcsFileName, _countof(sd.wcsFileName), wcsFilePath);
sd.eReqType = TYPE_DOWNLOAD;
sd.ullTimeStamp = GetTickCount();
nCurr++;
memcpy(g_pb, &sd, sizeof(sd));
}
}
}
下面的 C# 部分:
private void Button_MouseUp(object sender, RoutedEventArgs e)
{
Console.WriteLine("Click");
FileStream fs = File.Open(@"C:\\Users\\test\\Documents\\2134\\test.dat", FileMode.Open, FileAccess.ReadWrite); // Error Here! IOException: The file is being used by another process.
using (var mmf = MemoryMappedFile.CreateFromFile(fs, "mmf", 0, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true))
{
using (var accessor = mmf.CreateViewAccessor(0, 544))
{
DWORD dwCurrent;
accessor.Read(0, out dwCurrent);
Console.WriteLine("Hello" + dwCurrent);
}
}
}
关于实现两个进程之间的文件共享有什么想法吗?
There are two processes: one written in C++ and the other written in C#.
Simply, C++ process will create a file name "test.dat", map the file to its memory, and keep on writing on it.
C# process on the other hand will open the file and read whenever there is a change on the memory.
The problem is that on the C# end, it does not let me open the file. (IOException saying the other process is in use"
Here is what I've tested.
//C++
// Test create & open
void CTestDlg::OnBnClickedBtn1()
{
WCHAR wcsDebug[1024];
HANDLE hFile, hMapFile;
UINT size = sizeof(syncData);
hFile = CreateFile(L"C:\\Users\\test\\Documents\\2134\\test.dat", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
hMapFile = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, NULL);
if (hMapFile)
{
g_pb = (BYTE*)MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
}
}
}
// Test Writing
void CLibTestDlg::OnBnClickedBtn2()
{
WCHAR sz[] = L"C:\\Users\\test\\Documents\\2134\\";
WCHAR wcsFilePath[MAX_PATH];
CString str;
GetDlgItemText(IDC_EDIT_FID, str);
if (str != L"\0")
{
swprintf_s(wcsFilePath, _countof(wcsFilePath), L"%s%s", sz, str.GetBuffer());
if (g_pb)
{
syncData sd;
sd.dwCurrent = nCurr;
sd.dwTotal = 15;
sd.eSyncType = TYPE_DOWNLOAD;
StringCchCopy(sd.wcsFileName, _countof(sd.wcsFileName), wcsFilePath);
sd.eReqType = TYPE_DOWNLOAD;
sd.ullTimeStamp = GetTickCount();
nCurr++;
memcpy(g_pb, &sd, sizeof(sd));
}
}
}
C# portion below:
private void Button_MouseUp(object sender, RoutedEventArgs e)
{
Console.WriteLine("Click");
FileStream fs = File.Open(@"C:\\Users\\test\\Documents\\2134\\test.dat", FileMode.Open, FileAccess.ReadWrite); // Error Here! IOException: The file is being used by another process.
using (var mmf = MemoryMappedFile.CreateFromFile(fs, "mmf", 0, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true))
{
using (var accessor = mmf.CreateViewAccessor(0, 544))
{
DWORD dwCurrent;
accessor.Read(0, out dwCurrent);
Console.WriteLine("Hello" + dwCurrent);
}
}
}
Any ideas on approaching the file sharing between the two processes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
FileStream
默认为 仅允许读取共享,这与您打开 C++ 的方式不兼容文件。您还需要请求写入共享:FileStream
defaults to only allowing read sharing which is not compatible with how you've opened your c++ file. You need to request write sharing too: