windows下共享内存使用方法较 linux 而言微微复杂

  • 示例实现的功能

    有一个视频文件,一块内存区域 ;

    程序 A,将该视频写入该内存区域 ;

    程序 B,从该内存区域读取该视频 ;

    

  • 代码模块实现

  程序 A:main.h

 #ifndef MAIN_H
#define MAIN_H
#include <tchar.h>
#include <fstream>
#include <math.h>
#include <Windows.h> #include<opencv2/opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
#include<iostream> using namespace std;
using namespace cv; #define IMGWIDTH 1920
#define IMGHEIGHT 1080 #define FRAME_SIZE IMGWIDTH*IMGHEIGHT //每帧图像(单通道)的大小
#define BUF_SIZE FRAME_SIZE*5 //设定共享内存总大小(图像头信息 + RGB图像数据信息);
TCHAR shareZoneName[] = TEXT("share_Image"); //共享内存的名字 #define ORIGINAL_IMAGE_HEAD (char*)pBuf+FRAME_SIZE*0 //图像头信息首地址
#define ORIGINAL_IMAGE_DATA (char*)pBuf+FRAME_SIZE*2 //图像数据信息首地址 HANDLE hMapFile; //这块共享内存的句柄
LPCTSTR pBuf; //这块共享内存的首地址 typedef struct
{
int width; //图像宽度
int height; //图像的高度
int frame_no; //该帧图像的帧序号
}imgInfHead; //自定义的一个图像头结构体 #endif

  程序 A: main.cpp

 #include"main.hpp"

 using namespace std;
using namespace cv; // 创建共享内存, 通过句柄 hMapFile,获取共享内存首地址 pBuf
int createFileMapping()
{
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
, // maximum object size (high-order DWORD)
BUF_SIZE, // maximum object size (low-order DWORD)
shareZoneName); // name of mapping object if (hMapFile == NULL)
{
printf("Could not create file mapping object (%d).\n",
GetLastError());
return ;
} pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
,
,
BUF_SIZE); if (pBuf == NULL)
{
printf("Could not map view of file (%d).\n",
GetLastError()); CloseHandle(hMapFile); return ;
}
return ;
} //将 图像头 和 图像数据信息 写入到共享内存中
void copyToMemory(IplImage* IplImageOriginal, int frame_no)
{
if (IplImageOriginal->imageData == NULL)
{
cout << "fail copy to memory!" << endl;
return;
} imgInfHead img_inf_head_original; img_inf_head_original.width = IplImageOriginal->width;
img_inf_head_original.height = IplImageOriginal->height;
img_inf_head_original.frame_no = frame_no; memcpy(ORIGINAL_IMAGE_HEAD, &img_inf_head_original, sizeof(imgInfHead)); //在 共享内存 中保存图像头信息
memcpy(ORIGINAL_IMAGE_DATA, IplImageOriginal->imageData,
          IplImageOriginal->width*IplImageOriginal->height*IplImageOriginal->nChannels); //在 共享内存 中保存图像信息
} int main()
{
VideoCapture capture("VIDEO.mp4"); if (!capture.isOpened())
{
std::cout << "open video failed...!" << endl;
return ;
} createFileMapping(); //创建共享内存 Mat Image;
int frame_no = ;
IplImage* IplImageOrigal = cvCreateImage(Size(IMGWIDTH, IMGHEIGHT), , ); while ( true )
{
capture.read( Image ); if ( Image.empty() )
{
std::cout << "OVER!" << endl;
break;
} IplImageOrigal = &IplImage(Image);
copyToMemory(IplImageOrigal, frame_no); frame_no++;
} CloseHandle(hMapFile);
return ;
}

  程序 B:main.h

 #ifndef MAIN_H
#define MAIN_H #include <tchar.h>
#include <fstream>
#include <math.h>
#include <Windows.h> #include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp> #include <string.h>
#include <iostream> using namespace std;
using namespace cv; //单帧图像长宽
#define IMGWIDTH 1920
#define IMGHEIGHT 1080 #define FRAME_SIZE IMGWIDTH*IMGHEIGHT //单帧大小
#define BUF_SIZE FRAME_SIZE*5 //设定共享内存总大小
#define ORIGINAL_IMAGE_HEAD (char*)pBuf+FRAME_SIZE*0 //图像头首地址
#define ORIGINAL_IMAGE_DATA (char*)pBuf+FRAME_SIZE*2 //图像数据首地址 TCHAR shareZoneName_getSrcImg[] = TEXT("share_Image");
HANDLE hMapFile; //共享内存 句柄
LPCTSTR pBuf; //共享内存 所映射到的 首地址 typedef struct
{
int width;
int height;
int frame_no;
}imgInfHead; //自定义的一个图像头结构体 #endif

  程序 B:main.cpp

 #include "main.h"

 //打开共享内存(通过 共享内存 名称获取对应共享内存句柄,并获取共享内存首地址)
int openFileMapping()
{
hMapFile = OpenFileMapping(
FILE_MAP_ALL_ACCESS, // read/write access
FALSE, // do not inherit the name
shareZoneName_getSrcImg); // name of mapping object if (hMapFile == NULL)
{
printf("Could not open file mapping object (%d).\n", GetLastError());
return ;
} pBuf = (LPTSTR)MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
,
,
BUF_SIZE); if (pBuf == NULL)
{
printf("Could not map view of file (%d).\n", GetLastError());
CloseHandle(hMapFile);
return ;
}
return ;
} //将共享内存中的图像读取
int copyImageFromMemory(IplImage* &IplImageoOrignal, int* frame_no_adrr)
{
imgInfHead img_inf_head_orginal; memcpy(&img_inf_head_orginal, ORIGINAL_IMAGE_HEAD, sizeof(imgInfHead));
*frame_no_adrr = img_inf_head_orginal.frame_no; //获取该帧图像的 帧序号 IplImageoOrignal = cvCreateImage(cvSize(img_inf_head_orginal.width, img_inf_head_orginal.height), , );
int channels = IplImageoOrignal->nChannels; memcpy(IplImageoOrignal->imageData, ORIGINAL_IMAGE_DATA, img_inf_head_orginal.width*img_inf_head_orginal.height*channels);
return ;
} int main()
{
IplImage* IplImageOriginal;
int frame_no; Mat image_result;
while (true)
{
int flag_accept = openFileMapping();
if (flag_accept)
{
continue;
} int flag_bad = copyImageFromMemory(IplImageOriginal, &frame_no);
if (flag_bad)
{
cout << "复制失败" << endl;
continue;
} Mat(IplImageOriginal).copyTo(image_result); // 转成Mat类型
if (image_result.empty())
{
cvReleaseImage(&IplImageOriginal);
continue;
} //将帧序号显示在图片上
std::stringstream ss;
std::string frame_no_s;
ss << frame_no;
ss >> frame_no_s;
putText(image_result, frame_no_s, cv::Point(, ), cv::FONT_HERSHEY_SIMPLEX, 2.0, cv::Scalar(, , ), , ); imshow("readShareMemImg", image_result);
waitKey();
} CloseHandle(hMapFile);
return ;
}

----------------------------------------------------------------------------------------------------------------------------

windows 下共享内存使用方法示例的更多相关文章

  1. C++ windows下共享内存

    转载:https://blog.csdn.net/tojohnonly/article/details/70246965 共享内存 (也叫内存映射文件) 主要是通过映射机制实现的 , Windows ...

  2. 在Linux下和Windows下遍历目录的方法及如何达成一致性操作

    最近因为测试目的需要遍历一个目录下面的所有文件进行操作,主要是读每个文件的内容,只要知道文件名就OK了.在Java中直接用File类就可以搞定,因为Java中使用了组合模式,使得客户端对单个文件和文件 ...

  3. 利用windows api共享内存通讯

    主要涉及CreateFile,CreateFileMapping,GetLastError,MapViewOfFile,sprintf,OpenFileMapping,CreateProcess Cr ...

  4. Linux和Windows下查看环境变量方法对比

    摘自:Linux和Windows下查看环境变量方法对比 一.查看所有环境变量的名称和值 Linux下:export Windows下:set 二.根据名称查该环境变量的值 Linux下:echo $环 ...

  5. Windows进程间通信--共享内存映射文件(FileMapping)--VS2012下发送和接收

    之前以为两个互不相关的程序a.exe b.exe通信就只能通过网络,人家说可以通过发消息,我还深以为不然,对此,我表示万分惭愧. 之前课本上说的进程间通信,有共享内存.管道等之类的,但没有自己操刀写过 ...

  6. Windows 下的内存泄漏检测方法

    在 Windows 下,可使用 Visual C++ 的 C Runtime Library(CRT) 检测内存泄漏. 首先,我们在.c或.cpp 文件首行插入这一段代码: #define _CRTD ...

  7. linux 下共享内存

    一.共享内存相关知识 所谓共享内存,就是多个进程间共同地使用同一段物理内存空间,它是通过将同一段物理内存映射到不同进程的 虚拟空间来实现的.由于映射到不同进程的虚拟空间中,不同进程可以直接使用,不需要 ...

  8. linux下共享内存mmap和DMA(直接访问内存)的使用 【转】

    转自:http://blog.chinaunix.net/uid-7374279-id-4413316.html 介绍Linux内存管理和内存映射的奥秘.同时讲述设备驱动程序是如何使用“直接内存访问” ...

  9. CUDA共享内存的使用示例

    CUDA共享内存使用示例如下:参考教材<GPU高性能编程CUDA实战>.P54-P65 教材下载地址:http://download.csdn.net/download/yizhaoyan ...

随机推荐

  1. 输入一个A和B,,A<=B,A>=1,B<=pow(10,18)计算F=B!/A!结果的最后一位

    *************************************************************************代理运行函数,判断结果,进行输出*********** ...

  2. Less循环

    Less循环 在Less中,mixin可以调用它自身.通过这种递归调用,再结合Guard表达式和模式匹配,就可以写出各种循环结构.如,使用循环来创建一个网格类: .generate-columns(4 ...

  3. C语言之找零钱

    #include<stdio.h>int main(){ int one,tow,five,num=1; for (one = 1; one < num*10; one++) { f ...

  4. WEB漏洞攻击之验证码绕过浅析

    最近安全部门对WEB系统进行了一次漏洞整改,发现了某个系统存在验证码绕过风险. 根据安全部门提供的信息,该漏洞构造场景是通过一层中间代理(Burpsuite Proxy)拦截客户端与服务端的请求,通过 ...

  5. bootstrap fileinput上传返回400,404,500 等错误替换

    $(".uploadfile").on('filebatchuploaderror', function(event, data, msg) { $(".file-err ...

  6. 38.Linux驱动调试-根据系统时钟定位出错位置

    当内核或驱动出现僵死bug,导致系统无法正常运行,怎么找到是哪个函数的位置导致的? 答,通过内核的系统时钟,因为它是由定时器中断产生的,每隔一定时间便会触发一次,所以当CPU一直在某个进程中时,我们便 ...

  7. javaScript 验证码 倒计时60秒

    <input type="button" id="btn" value="免费获取验证码" /> <script type ...

  8. SpringBoot入门

    简介 从本质上来说,Spring Boot就是Spring,它做了那些没有它你也会去做的Spring Bean配置.它使用"习惯优于配置"(项目中存在大量的配置,此外还内置了一个习 ...

  9. mov指令具体解释

    MOV指令能够在CPU内或CPU和存储器之间传送字或字节.它传送的信息能够从寄存器到寄存器,马上数到寄存器,马上数到存储单元,从存储单元到寄存器.从寄存器到存储单元,从寄存器或存储单元到除CS外的段寄 ...

  10. linux中硬链接与软链接

    硬链接记录的是目标的inode,软链接记录的是目标的路径. 软链接就像快捷方式,而软链接就像备份.软链接能够做跨分区的链接,而硬链接因为inode的缘故,仅仅能在本分区中做链接,所以软链接使用很多其它 ...