Разделяемая память

Описание: Разработка и отладка приложений. Упор на 3D-графику.

dyvniy M
Автор темы, Администратор
Администратор
Аватара
dyvniy M
Автор темы, Администратор
Администратор
Возраст: 41
Репутация: 1
Лояльность: 1
Сообщения: 3579
Зарегистрирован: Ср, 10 октября 2012
С нами: 11 лет 6 месяцев
Профессия: Программист
Откуда: Россия, Москва
ICQ Сайт Skype ВКонтакте

#1 dyvniy » Вт, 13 мая 2014, 16:54:00

Использование разделяемой памяти в динамически подключаемой библиотеке (DLL)

Спойлер
Пример ниже демонстрирует, как функция точки входа в DLL может использовать объект "проекция файла в память", чтобы установить память, которая может быть совместно использоваться процессами, загружающими DLL. Разделяемая память DLL сохраняется только до тех пор, пока DLL загружена. Приложения могут использовать функции SetSharedMem и GetSharedMem, чтобы получить доступ к совместно используемой памяти.

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

Вызвать функцию CreateFileMapping, чтобы получить дескриптор объекта "проекция файла в память". Первый процесс, который загружает DLL, создает объект "проекция файла в память". Последующие процессы открывают дескриптор существующего объекта. Дополнительную информацию, см. в статье Создание объекта "проецируемый файл".
Вызвать функцию MapViewOfFile, чтобы проецировать представление в виртуальное адресное пространство. Это дает возможность процессу получить доступ к совместно используемой памяти. Дополнительную информацию, см. в статье Создание представления данных файла.

Код: Выделить всё

// Функция точки входа в DLL подготавливает разделяемую 
// память используя именованный объект "проекция файла 
// в память". 

#include <windows.h> 
#include <memory.h> 
 
#define SHMEMSIZE 4096 
 
static LPVOID lpvMem 
= NULL;      // указатель на разделяемую
                                  // память
static HANDLE hMapObject = NULL;  // дескриптор отображенного
                                  // файла
 
BOOL DllMain
(HINSTANCE hinstDLL,  // дескриптор модуля DLL
    DWORD fdwReason,              // причина вызова 
    LPVOID lpvReserved)           // зарезервирован 
{ 
    BOOL fInit
, fIgnore; 
 
    switch 
(fdwReason) 
    
{ 
        
// DLL загружается соответствующим процессом 
        // инициализации или вызовом LoadLibrary. 
 
          case DLL_PROCESS_ATTACH
: 
 
            
// Создаем именованный объект "проекция файла".
 
            hMapObject 
= CreateFileMapping( 
                INVALID_HANDLE_VALUE
, // используем файл подкачки
                NULL,                 // атрибуты защиты по умолчанию
                PAGE_READWRITE,       // доступ к чтению/записи
                0,                    // размер: старшие 32 бита
                SHMEMSIZE,            // размер: младшие 32 бита
                "dllmemfilemap");     // имя объекта отображения
            if (hMapObject == NULL) 
                return FALSE
; 
 
            
// Первый процесс, который присоединяем к 
            // инициализируемой памяти.
 
            fInit 
= (GetLastError() != ERROR_ALREADY_EXISTS); 
 
            
// Получим указатель на отображение файла
            // в разделяемой памяти.
 
            lpvMem 
= MapViewOfFile( 
                hMapObject
,     // объект представления проецирования
                FILE_MAP_WRITE, // доступ к чтению записи
                0,              // старшее смещение:  от отображения
                0,              // младшее смещение:   начало
                0);             // по умолчанию: проекция всего файла            if (lpvMem == NULL) 
                return FALSE; 
 
            
// Инициализация памяти, если она для первого процесса.
 
            if 
(fInit) 
                memset
(lpvMem, '\0', SHMEMSIZE); 
 
            break
; 
 
        
// Связанный процесс создает новый поток. 
 
        case DLL_THREAD_ATTACH
: 
            break
; 
 
        
// Поток связанного процесса заканчивает работу.
 
        case DLL_THREAD_DETACH
: 
            break
; 
 
        
// DLL выгружается из процесса вследствие  
        // завершение работы процесса или вызова FreeLibrary. 

        case DLL_PROCESS_DETACH: 
 
            
// Отменяет отображение совместно используемой памяти
            // от адресного пространства процесса.
 
            fIgnore 
= UnmapViewOfFile(lpvMem); 
 
            
// Закрываем дескриптор процесса объекта 
            // "проекция файла в память".
 
            fIgnore 
= CloseHandle(hMapObject); 
 
            break
; 
 
        default
: 
          break
; 
     
} 
 
    return TRUE
; 
    UNREFERENCED_PARAMETER
(hinstDLL); 
    UNREFERENCED_PARAMETER
(lpvReserved); 
} 
 
// SetSharedMem устанавливает содержание совместно
// используемой памяти. 
 
VOID SetSharedMem
(LPSTR lpszBuf) 
{ 
    LPSTR lpszTmp
; 
 
    
// Получим адрес блока совместно используемой памяти.
 
    lpszTmp 
= (LPSTR) lpvMem; 
 
    
// Копируем символьную строку с нулем в конце в
    // совместно используемую память.
 
    while 
(*lpszBuf) 
        
*lpszTmp++ = *lpszBuf++; 
    
*lpszTmp = '\0'; 
} 
 
// GetSharedMem получает содержание совместно
// используемой памяти. 
 
VOID GetSharedMem
(LPSTR lpszBuf, DWORD cchSize) 
{ 
    LPSTR lpszTmp
; 
 
    
// Получаем адрес блока совместно используемой памяти.
 
    lpszTmp 
= (LPSTR) lpvMem; 
 
    
// Копируем совместно используемую память в буфер
    // вызывающей программы.
 
    while 
(*lpszTmp && --cchSize) 
        
*lpszBuf++ = *lpszTmp++; 
    
*lpszBuf = '\0'; 
}

Изображение

Название раздела: Программирование (под Desktop и Android)
Описание: Разработка и отладка приложений. Упор на 3D-графику.

Быстрый ответ


Введите код в точности так, как вы его видите. Регистр символов не имеет значения.
Код подтверждения
:) ;) :hihi: :P :hah: :haha: :angel: :( :st: :_( :cool: 8-| :beee: :ham: :rrr: :grr: :* :secret: :stupid: :music: Ещё смайлики…
   

Вернуться в «Программирование (под Desktop и Android)»

Кто сейчас на форуме (по активности за 15 минут)

Сейчас этот раздел просматривают: 106 гостей