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. 如何访问 Service?- 每天5分钟玩转 Docker 容器技术(99)

    前面我们已经学习了如何部署 service,也验证了 swarm 的 failover 特性.不过截止到现在,有一个重要问题还没有涉及:如何访问 service?这就是本节要讨论的问题. 为了便于分析 ...

  2. .net 系列:Expression表达式树、lambda、匿名委托 的使用

    首先定义一个泛型委托类型,如下: public delegate T Function<T>(T a, T b); 实现泛型委托的主体代码,并调用: public static strin ...

  3. redis在spring-boot中的应用

    Redis(REmote DIctionary Server) 是一个由Salvatore Sanfilippo写的key-value存储系统.Redis是一个开源的使用ANSI C语言编写.遵守BS ...

  4. smali语法(二)

    一.smali的包中信息 .class public Lcom/aaaaa; .super Lcom/bbbbb; .source "ccccc.java" 1.它是com.aaa ...

  5. 史上最全常用正则表达式(Javascript公众号推文)

    2017-04-13 zxin JavaScript很多不太懂正则的朋友,在遇到需要用正则校验数据时,往往是在网上去找很久,结果找来的还是不很符合要求.所以我最近把开发中常用的一些正则表达式整理了一下 ...

  6. Prim算法模板

    //Gang #include<iostream> #include<cstring> #include<algorithm> #include<cstdio ...

  7. Netty4 学习笔记之三:粘包和拆包

    前言 在上一篇Netty 心跳 demo 中,了解了Netty中的客户端和服务端之间的心跳.这篇就来讲讲Netty中的粘包和拆包以及相应的处理. 名词解释 粘包: 会将消息粘粘起来发送.类似吃米饭,一 ...

  8. C#使用ManagementObjectSearcher来获取系统信息时会有out of memory的异常

    在开发环境下,时不时出现out of memory的异常,最后是在服务界面重新启动 Windows Management Instrumentation后就好了.

  9. springmvc关于前台日期作为实体类对象参数类型转换错误

    页面报错: 后台错误: Field error in object 'user' on field 'birthday': rejected value [2013-06-24]; codes [ty ...

  10. java学习笔记之String类

    String类总结 String类概述: java.lang.String 类是字符串操作类 String类的常用构造方法: //1.直接赋值 String str= "hellojava& ...