0%

MFC_(二)-共享内存

Shared.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#pragma once

#include <mutex>

//// 定义共享内存的大小和名称
const DWORD SHARED_MEM_SIZE = 800 * 600 * 4;
const LPCTSTR SHARED_MEM_NAME = _T("SMTLCDM");

class CShare
{
public:
CShare();
~CShare();

public:
BOOL InitShareMem();
BOOL DestroyShareMem();

BOOL LockMem();
BOOL UnLockMem();

void WriteData(const char* buff, int len);
public:
void* m_hFileMap; //创建共享内存成功返回
char* m_pSharedMem; //映射共享内存的指针

void* m_sharedLock;
BOOL m_bhasLock;

};


Shared.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "stdafx.h"
#include "Share.h"

CShare::CShare()
{
m_hFileMap = NULL; //创建共享内存成功返回
m_pSharedMem = NULL; //映射共享内存的指针

m_sharedLock = NULL;
m_bhasLock = FALSE;
}

CShare::~CShare()
{
UnLockMem();
DestroyShareMem();
}

BOOL CShare::InitShareMem()
{
// 尝试打开名为 "SMTLCDM_Mutex" 的互斥锁
m_sharedLock = OpenMutex(NULL, false, TEXT("SMTLCDM_Mutex"));

// 如果未能打开互斥锁,则创建一个新的互斥锁
if (m_sharedLock == NULL)
{
m_sharedLock = CreateMutex(NULL, FALSE, TEXT("SMTLCDM_Mutex"));
if (!m_sharedLock) // 检查互斥锁创建是否成功
{
return false; // 创建失败,返回 false
}
}

void* buff = NULL; // 定义用于映射的指针

// 创建文件映射对象,仅在尚未创建时执行
if (NULL == m_hFileMap)
{
m_hFileMap = CreateFileMapping(
(HANDLE)INVALID_HANDLE_VALUE, // 使用页文件作为共享内存
NULL, // 安全描述符
PAGE_READWRITE, // 读写权限
0, // 最大大小的高位
SHARED_MEM_SIZE, // 最大大小的低位
SHARED_MEM_NAME // 共享内存的名称
);

// 映射共享内存指针
buff = MapViewOfFile(
m_hFileMap, // 文件映射对象的句柄
FILE_MAP_READ | FILE_MAP_WRITE, // 读写权限
0, 0, 0 // 偏移量和映射大小(映射整个共享内存)
);
}
else // 如果已经创建过文件映射对象,则直接映射
{
buff = MapViewOfFile(
m_hFileMap, // 文件映射对象的句柄
FILE_MAP_READ | FILE_MAP_WRITE, // 读写权限
0, 0, 0 // 偏移量和映射大小(映射整个共享内存)
);
}

// 检查映射是否成功
if (buff == (void*)-1)
{
// 如果映射失败,解除文件映射,关闭内存映射文件对象句柄
::UnmapViewOfFile(buff);
::CloseHandle(m_hFileMap);
m_hFileMap = NULL; // 重新设置为 NULL
return FALSE; // 返回失败
}

// 成功映射共享内存,将指针赋值给成员变量
m_pSharedMem = (char*)buff;
return TRUE; // 返回成功
}


BOOL CShare::DestroyShareMem()
{
if (m_pSharedMem)
{
::UnmapViewOfFile(m_pSharedMem);
m_pSharedMem = nullptr;
}
if (m_hFileMap != nullptr)
{
m_hFileMap = nullptr;
}
return TRUE;
}

BOOL CShare::LockMem()
{
if (m_sharedLock)
{
DWORD timeout = 1;
DWORD waitres;
waitres = WaitForSingleObject(m_sharedLock, timeout);
if (waitres == WAIT_OBJECT_0) {
m_bhasLock = TRUE;
return TRUE;
}
if (waitres == WAIT_TIMEOUT) {
m_bhasLock = FALSE;
return FALSE;
}
return TRUE;
}

m_bhasLock = FALSE;
return FALSE;
}

BOOL CShare::UnLockMem()
{
if (m_sharedLock)
{
ReleaseMutex(m_sharedLock);
m_bhasLock = FALSE;
}

return TRUE;
}

void CShare::WriteData(const char* buff, int len)
{
memcpy(m_pSharedMem, buff, len);
}

dlg.cp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
void CLCDMDlg::OnPaint()
{
// 调用基类的 OnPaint 函数
CDialog::OnPaint();
CRect rcClient;
// 获取客户区的矩形区域
GetClientRect(&rcClient);

// 获取窗口的设备上下文
CDC *pDC = this->GetDC();

static int nTi = 0; // 用于控制绘制频率
CDC MemDC; // 内存设备上下文
CBitmap MemBitMap; // 内存位图

// 创建与窗口兼容的内存设备上下文
MemDC.CreateCompatibleDC(pDC);
// 创建与窗口兼容的位图
MemBitMap.CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
// 选择位图到内存设备上下文中
CBitmap *pOldBit = MemDC.SelectObject(&MemBitMap);

// 使用 GDI+ 进行绘图
Gdiplus::Graphics g(MemDC);
CLCDMApp *pApp = (CLCDMApp *)AfxGetApp(); // 获取应用程序实例

// 检查当前页面索引是否有效
if (pApp->g_nCurrentPage < m_pFUI.size())
{
// 在内存 DC 上绘制当前页面的内容
m_pFUI.at(pApp->g_nCurrentPage)->OnPaint(g);
m_pFUI.at(pApp->g_nCurrentPage)->OnPaint(&MemDC);
}

// 将内存 DC 的内容复制到窗口的设备上下文
pDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), &MemDC, 0, 0, SRCCOPY);

// 创建一个缓冲区用于存储位图数据
std::vector<unsigned char> colorBuff;
colorBuff.resize(rcClient.Width() * rcClient.Height() * 4);
// 获取位图的像素数据
MemBitMap.GetBitmapBits(colorBuff.size(), &colorBuff[0]);

// 锁定共享内存以进行写入
m_pShare->LockMem();
if (m_pShare != NULL && m_pShare->m_bhasLock)
{
// 将颜色缓冲区数据写入共享内存
m_pShare->WriteData((const char*)(char*)&colorBuff[0], rcClient.Width() * rcClient.Height() * 4);
}
// 解锁共享内存
m_pShare->UnLockMem();

// 清理资源
MemBitMap.DeleteObject(); // 删除位图对象
MemDC.DeleteDC(); // 删除内存设备上下文
ReleaseDC(pDC); // 释放窗口的设备上下文
}

-------------本文结束感谢您的阅读-------------