windows 下共享内存使用方法示例
windows下共享内存使用方法较 linux 而言微微复杂
- 示例实现的功能
有一个视频文件,一块内存区域 ;
程序 A,将该视频写入该内存区域 ;
程序 B,从该内存区域读取该视频 ;
- 代码模块实现
程序 A:main.h
1 #ifndef MAIN_H
2 #define MAIN_H
3 #include <tchar.h>
4 #include <fstream>
5 #include <math.h>
6 #include <Windows.h>
7
8 #include<opencv2/opencv.hpp>
9 #include<opencv2/highgui/highgui.hpp>
10 #include<opencv2/imgproc/imgproc.hpp>
11 #include<iostream>
12
13 using namespace std;
14 using namespace cv;
15
16 #define IMGWIDTH 1920
17 #define IMGHEIGHT 1080
18
19 #define FRAME_SIZE IMGWIDTH*IMGHEIGHT //每帧图像(单通道)的大小
20 #define BUF_SIZE FRAME_SIZE*5 //设定共享内存总大小(图像头信息 + RGB图像数据信息);
21 TCHAR shareZoneName[] = TEXT("share_Image"); //共享内存的名字
22
23 #define ORIGINAL_IMAGE_HEAD (char*)pBuf+FRAME_SIZE*0 //图像头信息首地址
24 #define ORIGINAL_IMAGE_DATA (char*)pBuf+FRAME_SIZE*2 //图像数据信息首地址
25
26 HANDLE hMapFile; //这块共享内存的句柄
27 LPCTSTR pBuf; //这块共享内存的首地址
28
29 typedef struct
30 {
31 int width; //图像宽度
32 int height; //图像的高度
33 int frame_no; //该帧图像的帧序号
34 }imgInfHead; //自定义的一个图像头结构体
35
36 #endif
程序 A: main.cpp
1 #include"main.hpp"
2
3 using namespace std;
4 using namespace cv;
5
6 // 创建共享内存, 通过句柄 hMapFile,获取共享内存首地址 pBuf
7 int createFileMapping()
8 {
9 hMapFile = CreateFileMapping(
10 INVALID_HANDLE_VALUE, // use paging file
11 NULL, // default security
12 PAGE_READWRITE, // read/write access
13 0, // maximum object size (high-order DWORD)
14 BUF_SIZE, // maximum object size (low-order DWORD)
15 shareZoneName); // name of mapping object
16
17 if (hMapFile == NULL)
18 {
19 printf("Could not create file mapping object (%d).\n",
20 GetLastError());
21 return 1;
22 }
23
24
25 pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
26 FILE_MAP_ALL_ACCESS, // read/write permission
27 0,
28 0,
29 BUF_SIZE);
30
31 if (pBuf == NULL)
32 {
33 printf("Could not map view of file (%d).\n",
34 GetLastError());
35
36 CloseHandle(hMapFile);
37
38 return 1;
39 }
40 return 0;
41 }
42
43 //将 图像头 和 图像数据信息 写入到共享内存中
44 void copyToMemory(IplImage* IplImageOriginal, int frame_no)
45 {
46 if (IplImageOriginal->imageData == NULL)
47 {
48 cout << "fail copy to memory!" << endl;
49 return;
50 }
51
52 imgInfHead img_inf_head_original;
53
54 img_inf_head_original.width = IplImageOriginal->width;
55 img_inf_head_original.height = IplImageOriginal->height;
56 img_inf_head_original.frame_no = frame_no;
57
58 memcpy(ORIGINAL_IMAGE_HEAD, &img_inf_head_original, sizeof(imgInfHead)); //在 共享内存 中保存图像头信息
59 memcpy(ORIGINAL_IMAGE_DATA, IplImageOriginal->imageData,
IplImageOriginal->width*IplImageOriginal->height*IplImageOriginal->nChannels); //在 共享内存 中保存图像信息
60 }
61
62 int main()
63 {
64 VideoCapture capture("VIDEO.mp4");
65
66 if (!capture.isOpened())
67 {
68 std::cout << "open video failed...!" << endl;
69 return 0;
70 }
71
72 createFileMapping(); //创建共享内存
73
74 Mat Image;
75 int frame_no = 1;
76 IplImage* IplImageOrigal = cvCreateImage(Size(IMGWIDTH, IMGHEIGHT), 8, 3);
77
78 while ( true )
79 {
80 capture.read( Image );
81
82 if ( Image.empty() )
83 {
84 std::cout << "OVER!" << endl;
85 break;
86 }
87
88 IplImageOrigal = &IplImage(Image);
89 copyToMemory(IplImageOrigal, frame_no);
90
91 frame_no++;
92 }
93
94 CloseHandle(hMapFile);
95 return 0;
96 }
程序 B:main.h
1 #ifndef MAIN_H
2 #define MAIN_H
3
4 #include <tchar.h>
5 #include <fstream>
6 #include <math.h>
7 #include <Windows.h>
8
9 #include <opencv2/opencv.hpp>
10 #include <opencv2/highgui/highgui.hpp>
11 #include <opencv2/imgproc/imgproc.hpp>
12
13 #include <string.h>
14 #include <iostream>
15
16 using namespace std;
17 using namespace cv;
18
19 //单帧图像长宽
20 #define IMGWIDTH 1920
21 #define IMGHEIGHT 1080
22
23 #define FRAME_SIZE IMGWIDTH*IMGHEIGHT //单帧大小
24 #define BUF_SIZE FRAME_SIZE*5 //设定共享内存总大小
25 #define ORIGINAL_IMAGE_HEAD (char*)pBuf+FRAME_SIZE*0 //图像头首地址
26 #define ORIGINAL_IMAGE_DATA (char*)pBuf+FRAME_SIZE*2 //图像数据首地址
27
28 TCHAR shareZoneName_getSrcImg[] = TEXT("share_Image");
29 HANDLE hMapFile; //共享内存 句柄
30 LPCTSTR pBuf; //共享内存 所映射到的 首地址
31
32 typedef struct
33 {
34 int width;
35 int height;
36 int frame_no;
37 }imgInfHead; //自定义的一个图像头结构体
38
39 #endif
程序 B:main.cpp
1 #include "main.h"
2
3 //打开共享内存(通过 共享内存 名称获取对应共享内存句柄,并获取共享内存首地址)
4 int openFileMapping()
5 {
6 hMapFile = OpenFileMapping(
7 FILE_MAP_ALL_ACCESS, // read/write access
8 FALSE, // do not inherit the name
9 shareZoneName_getSrcImg); // name of mapping object
10
11 if (hMapFile == NULL)
12 {
13 printf("Could not open file mapping object (%d).\n", GetLastError());
14 return 1;
15 }
16
17 pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
18 FILE_MAP_ALL_ACCESS, // read/write permission
19 0,
20 0,
21 BUF_SIZE);
22
23 if (pBuf == NULL)
24 {
25 printf("Could not map view of file (%d).\n", GetLastError());
26 CloseHandle(hMapFile);
27 return 1;
28 }
29 return 0;
30 }
31
32 //将共享内存中的图像读取
33 int copyImageFromMemory(IplImage* &IplImageoOrignal, int* frame_no_adrr)
34 {
35 imgInfHead img_inf_head_orginal;
36
37 memcpy(&img_inf_head_orginal, ORIGINAL_IMAGE_HEAD, sizeof(imgInfHead));
38 *frame_no_adrr = img_inf_head_orginal.frame_no; //获取该帧图像的 帧序号
39
40 IplImageoOrignal = cvCreateImage(cvSize(img_inf_head_orginal.width, img_inf_head_orginal.height), 8, 3);
41 int channels = IplImageoOrignal->nChannels;
42
43 memcpy(IplImageoOrignal->imageData, ORIGINAL_IMAGE_DATA, img_inf_head_orginal.width*img_inf_head_orginal.height*channels);
44 return 0;
45 }
46
47 int main()
48 {
49 IplImage* IplImageOriginal;
50 int frame_no;
51
52
53
54 Mat image_result;
55 while (true)
56 {
57 int flag_accept = openFileMapping();
58 if (flag_accept)
59 {
60 continue;
61 }
62
63 int flag_bad = copyImageFromMemory(IplImageOriginal, &frame_no);
64 if (flag_bad)
65 {
66 cout << "复制失败" << endl;
67 continue;
68 }
69
70 Mat(IplImageOriginal).copyTo(image_result); // 转成Mat类型
71 if (image_result.empty())
72 {
73 cvReleaseImage(&IplImageOriginal);
74 continue;
75 }
76
77 //将帧序号显示在图片上
78 std::stringstream ss;
79 std::string frame_no_s;
80 ss << frame_no;
81 ss >> frame_no_s;
82 putText(image_result, frame_no_s, cv::Point(0, 50), cv::FONT_HERSHEY_SIMPLEX, 2.0, cv::Scalar(0, 255, 255), 8, 10);
83
84 imshow("readShareMemImg", image_result);
85 waitKey(1);
86 }
87
88 CloseHandle(hMapFile);
89 return 0;
90 }
----------------------------------------------------------------------------------------------------------------------------
技术能改变世界,却改变不了人心