Доброго всем времени суток.
Возникла у меня проблема с CreateFileMapping...
Должен происходить примерно такой процесс:
1) Запускается приложение на unmanaged C++ (А)
2) А создаёт file mapping именованный
3) А создаёт евент именованный
4) А запускает приложение на C# (managed) (Б)
5) А начинает ждать созданный евент
6) Б открывает file mapping созданный A и записывает туда какие-то данные
7) Б запускает евент созданный в А
8) А считывает данные из file mapping и закрывается
примерно так выглядит А:
HANDLE hFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, L"TestFile");
HANDLE hEvent = CreateEvent(NULL, true, false, L"TestEvent");
WaitForSingleObject(hEvent, INFINITE);
//Запуск Б
CloseHandle(hEvent);
SetFilePointer(hFile, 0, NULL, SEEK_SET);
BYTE* data = new BYTE[4];
DWORD count;
ReadFile(hFile, data, 4, &count, NULL);
for (int i = 0; i < count; i++){
cout << data[i];
}
CloseHandle(hFile);
примерно так выглядит Б:
[DllImport("kernel32.dll")]
private static extern IntPtr CreateFileMapping(IntPtr hFile, IntPtr lpFileMappingAttributes, int flProtect, int dwMaximumSizeHigh, int dwMaximumSizeLow, string lpName);
[DllImport("kernel32.dll")]
private static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer, int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, IntPtr lpOverlapped);
[DllImport("Kernel32.dll")]
static extern int SetFilePointer(IntPtr hFile, int lDistanceToMove, ref int lpDistanceToMoveHigh, EMoveMethod dwMoveMethod);
private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
private const int PAGE_READWRITE = 4;
IntPtr file = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, PAGE_READWRITE, 0, 4096, "TestFile");
int len;
byte[] data = new byte[4];
for(int i = 0; i< data.Length;i++) {
data[i] = (byte)i;
}
WriteFile(file, data, data.Length, out len, IntPtr.Zero);
Console.WriteLine(len);
int pos2 = 0;
len = SetFilePointer(file, 0, ref pos2, EMoveMethod.End);
Console.WriteLine(len);
EventWaitHandle handle = EventWaitHandle.OpenExisting("TestEvent");
handle.Set();
В Б удаётся записать 0 байт, в А соответственно столько же считать...
кто-нибудь сталкивался с чем-нибудь подобным?
Здравствуйте, BlackShadow, Вы писали:
BS>Доброго всем времени суток.
[skipped]
BS>В Б удаётся записать 0 байт, в А соответственно столько же считать...
BS>кто-нибудь сталкивался с чем-нибудь подобным?
что-то мне подсказывает, что где-то возникает ошибка, которую ты не обрабатываешь.
Конкретно ты забываешь отмапить сам маппинг hFile через MapViewOfFile()
Posted via << RSDN@Home 1.2.0 alpha rev. 784>>
Оигенно ж вы файлмаппинг юзаете. И офигенно тут читают сообщения на форуме
Здравствуйте, BlackShadow, Вы писали:
BS>примерно так выглядит А:
BS>BS> HANDLE hFile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 4096, L"TestFile");
BS> HANDLE hEvent = CreateEvent(NULL, true, false, L"TestEvent");
BS> WaitForSingleObject(hEvent, INFINITE);
BS>//Запуск Б
BS> CloseHandle(hEvent);
BS> SetFilePointer(hFile, 0, NULL, SEEK_SET);
BS> BYTE* data = new BYTE[4];
BS> DWORD count;
BS> ReadFile(hFile, data, 4, &count, NULL);
BS> for (int i = 0; i < count; i++){
BS> cout << data[i];
BS> }
BS> CloseHandle(hFile);
BS>
Мне кажется что ты не понимаешь базовых принципов file mapping.
file mapping это проекция "тела" файла на область памяти. Т.е. после установки file mapping у тебя есть указатль на память с пом. которого тв можешь писать в файл как в память.
См. имплементацию class mm_file в
http://www.codeproject.com/cpp/flattables.asp
Спасибо всем, кто среагировал на мой вопрос.
Действительно, я прокололся с азами использования отображения — криво понял MSDN. Стоило добавить MapViewOfFile, как всё заработало. Хотелось конечно избежать unsafe-кода, но похоже не судьба