• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
MKT-porter
博客园    首页    新随笔    联系   管理    订阅  订阅
共享内存(1)c++2c++

 

正常工程学习结构

发送端

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
#include <string>
 
#define Shm_addrees 1201

#define IMAGE_W 1202  //图像宽
#define IMAGE_H  676  //图像高
#define IMAGE_SIZE  IMAGE_W*IMAGE_H*3 //图片像素总大小 3通道彩色
using namespace std;
 

typedef struct _ShareData
{
	int  flag;
	int rows;
	int cols;
	char imgdata[IMAGE_SIZE];//之前用了cv::Mat不行,因为无法在结构体里初始化大小
}ShareData;



int Send_data2_share(ShareData *pShareData){

	
 
	int i = 0;
	while(1)
	{
		while(pShareData->flag == 0)
		{
			getchar();
                        
			cv::Mat Img=cv::imread("../data_img/1.jpg",cv::IMREAD_COLOR);

			if(Img.data== nullptr)//nullptr是c++11新出现的空指针常量
			{
				printf("图片文件不存在\n");
				return 0;
				}
			else{
            	printf("图片文件存在\n");
			}
			
			


			//3-1共享内存保存图像宽和高
			pShareData->rows =Img.rows;
			pShareData->cols =  Img.cols;

            //3-2共享内存保存图像数据
			int size = Img.cols * Img.rows * Img.channels();	
			char *cvoutImg = (char*)Img.data;
			memcpy(pShareData->imgdata, cvoutImg, size);

			//3-3共享内存保存标志位          
			pShareData->flag = 1;
		}
    }	
}
 
int main()
{


   //1创建共享内存
	int shmid = shmget((key_t)Shm_addrees, sizeof(ShareData), 0666|IPC_CREAT);
	//2映射共享内存地址  shm指针记录了起始地址
	void *shm = shmat(shmid, (void*)0, 0);//如果创建一个函数每次调用都执行,需要执行完释放一下shmdt
    printf("共享内存地址 : %p\n", (int *)(shm));

   //2-1映射共性内存类型-访问共享内存数据
	ShareData *pShareData= (ShareData*)shm;
	pShareData->flag = 0;

    //使用共享内存数据
    Send_data2_share(pShareData);


    //4断开映射 ,保证下次访问不被占用
	shmdt(shm);
	//5释放共享内存地址
	shmctl(shmid, IPC_RMID, 0);


	return 0;
}

  

 

 

 

接收端

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
 
  
#define Shm_addrees 1201
#define IMAGE_W 1202  //图像宽
#define IMAGE_H  676  //图像高
#define IMAGE_SIZE  IMAGE_W*IMAGE_H*3 //图片像素总大小 3通道彩色  最大大小
using namespace std;
 
 
typedef struct _ShareData
{
	int  flag;
	int rows;
	int cols;
	char imgdata[IMAGE_SIZE];
}ShareData;
 


int Rec_share2_data(ShareData *pShareData){

   
	while(1)
	{
		//3-1共享内存读取标志位      
		if(pShareData->flag == 1)
		{
			//3-2从共享内存获取图像高和宽
			int IMAGE_h=pShareData->rows;//从共享内存获取图像高
			int IMAGE_w=pShareData->cols;//从共享内存获取图像宽

           	//3-3共享内存读取图像数据	
			cv::Mat cvoutImg = cv::Mat(IMAGE_h,IMAGE_w,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth
			int size = cvoutImg.cols * cvoutImg.rows * cvoutImg.channels();
			memcpy((char*)cvoutImg.data, pShareData->imgdata,size);

			cv::imshow("RecData_Show",cvoutImg);
			cv::waitKey(1000);
			printf("数据跟新一次");

		    //3-4共享内存修改标志位
			pShareData->flag = 0;
		}       
	}

}


int main()
{

   //1创建共享内存
	int shmid = shmget((key_t)Shm_addrees, sizeof(ShareData), 0666|IPC_CREAT);
	//2映射共享内存地址
	void *shm = shmat(shmid, (void*)0, 0);//如果创建一个函数每次调用都执行,需要执行完释放一下shmdt
   //2-1映射共性内存类型
    ShareData *pShareData = (ShareData*)shm;


    //3数据访问
    Rec_share2_data( pShareData);

    //4断开映射 ,保证下次访问不被占用
	shmdt(shm);
	//5释放共享内存地址
	shmctl(shmid, IPC_RMID, 0);

	return 0;
} 

  

 

 

 

 

 

 

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

 

类封装工程

 

 

 

 

编译测试

cd build
cmake ..
make

  

 

 

执行

 

 

 

 

 

 

 

使用讲解

 正常调用

 

 

 

 

 

 具体代码

 

 

 

 

 CMakeLists.txt

 

 

# cmake needs this line
cmake_minimum_required(VERSION 3.1)


# Define project name
project(opencv_example_project)

find_package(OpenCV REQUIRED)

message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")





# Declare the executable target built from your sources

add_executable(send ApiShare.cpp send_example.cpp)
add_executable(client ApiShare.cpp recive_example.cpp)


# Link your application with OpenCV libraries
target_link_libraries(send ${OpenCV_LIBS})
target_link_libraries(client ${OpenCV_LIBS})

  

调用类

修改内容

1修改图像分辨率

2修改数据结构,自定义扩展


#define IMAGE_W 1202 //图像宽

#define IMAGE_H 676 //图像高

3修改共享内存标识      

#define Shm_addrees 1201 //共享内存地址标识

ApiShare.cpp

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
 

namespace MyShare{

 class Share_class
{
    //变量定义
	public:

			#define Shm_addrees 1201 //共享内存地址标识

			#define IMAGE_W 1202  //图像宽
			#define IMAGE_H  676  //图像高
			#define IMAGE_SIZE  IMAGE_W*IMAGE_H*3 //图片像素总大小 3通道彩色

             //共享内存结构
			 typedef struct _ShareData
			{
				int  flag;
				int rows;
				int cols;
				char imgdata[IMAGE_SIZE];//之前用了cv::Mat不行,因为无法在结构体里初始化大小
			}ShareData;



	     	//1创建共享内存
			int shmid = shmget((key_t)Shm_addrees, sizeof(ShareData), 0666|IPC_CREAT);
			//2映射共享内存地址  shm指针记录了起始地址
			void *shm = shmat(shmid, (void*)0, 0);//如果创建一个函数每次调用都执行,需要执行完释放一下shmdt
			//printf("共享内存地址 : %p\n", (int *)(shm));

	    	//2-1映射共性内存类型-访问共享内存数据
	 		ShareData *pShareData= (ShareData*)shm;
			//pShareData->flag = 0;

			cv::Mat cvoutImg = cv::Mat(IMAGE_H,IMAGE_W,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth


    //函数定义
	public:
	    //1初始化执行
		Share_class(){  
			printf("共享内存地址 : %p\n", (int *)(shm));
			 pShareData->flag = 0;           
		 }//1构造函数
		 
		 //0销毁执行
		~Share_class() {
		    	cout<<"析构函数执行"<<endl;
		}	//0结束销毁函数


	    //3销毁共享内存
		int DestroyShare(){

					//4断开映射 ,保证下次访问不被占用
						shmdt(shm);
						//5释放共享内存地址
						shmctl(shmid, IPC_RMID, 0);
						cout<<"共享内存已经销毁"<<endl;

		}

		//2发送图像一张 ,并修改发送标志位1
		int Send_pic2_share_once(cv::Mat  Img){
	
			int i = 0;

				if(pShareData->flag == 0)
				{
					
								
				//cv::Mat Img=cv::imread("../data_img/1.jpg",cv::IMREAD_COLOR);

					if(Img.data== nullptr)//nullptr是c++11新出现的空指针常量
					{
						printf("图片文件不存在\n");
						return 0;
						}
					else{
					   	printf("图片文件存在\n");
					}
					
					


					//3-1共享内存保存图像宽和高
					pShareData->rows =Img.rows;
					pShareData->cols =  Img.cols;

					//3-2共享内存保存图像数据
					int size = Img.cols * Img.rows * Img.channels();	
					char *cvoutImg = (char*)Img.data;
					memcpy(pShareData->imgdata, cvoutImg, size);

					//3-3共享内存保存标志位          
					pShareData->flag = 1;
				}
			
			//getchar();
		}

		//从共享内存读取一张图片
		int  Rec_pic2_data_once(){ //cv::Mat &cvoutImg_in
			//3-1共享内存读取标志位      
			if(pShareData->flag == 1)
			{
				//3-2从共享内存获取图像高和宽
				int IMAGE_h=pShareData->rows;//从共享内存获取图像高
				int IMAGE_w=pShareData->cols;//从共享内存获取图像宽

				//3-3共享内存读取图像数据	
				//cv::Mat cvoutImg = cv::Mat(IMAGE_h,IMAGE_w,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth
				int size = cvoutImg.cols * cvoutImg.rows * cvoutImg.channels();
				memcpy((char*)cvoutImg.data, pShareData->imgdata,size);

                //cvoutImg.copyTo(cvoutImg_in);
				//cvoutImg_in=cvoutImg;

				//cv::imshow("RecData_Show",cvoutImg);
		    	//cv::waitKey(1);
				printf("数据跟新一次\n");



				//3-4共享内存修改标志位
				pShareData->flag = 0;
			}       
		}



};//类定义结束


}//namespace 定义

 

发送类

 

 send_example.cpp

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
#include <string>

#include  "ApiShare.cpp"
using namespace std;
 

int main()
{

	//1创建对象
    MyShare::Share_class useShare;
    
	//2-1发送数据-读取数据
	cv::Mat Img=cv::imread("../data_img/1.jpg",cv::IMREAD_COLOR);
    
	//2-2修改标志位--用来控制读取同步
	//useShare.pShareData->flag = 0;  //提醒。第一次初始化强制给0,清除上次程序残留结果,类初始化已经给0了

    //3发送图像
   while (1){
	   useShare.Send_pic2_share_once(Img);//发送一张图像

		if(useShare.pShareData->flag ==3){ //接收端读取成功并且将标志位修改成3 关闭
			break;
		}
   }
   //销毁
	useShare.DestroyShare(); //销毁共享内存

}

  

 

接受测试

 

 

 

recive_example.cpp

 

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <vector>
#include <string>

#include  "ApiShare.cpp"
using namespace std;
 

int main()
{
	//1创建对象
    MyShare::Share_class useShare;

    //2创建接受图像
    // cv::Mat cvoutImg = cv::Mat(676,1201,CV_8UC3,cv::Scalar(255, 255, 255));//bufHight,bufWidth

	//3接受图像
	while (1){

			useShare.Rec_pic2_data_once();//接受一张图像
            cv::Mat cvoutImg=useShare.cvoutImg;
      
		    cv::imshow("RecData_Show",cvoutImg);
		    char key=cv::waitKey(1);
			if(key=='q'){      useShare.pShareData->flag=3;     printf("按键退出");   break;}	
	}

	//销毁
    useShare.DestroyShare(); //销毁共享内存


	return 0;
}

  

  

 

posted on 2021-07-05 22:28  MKT-porter  阅读(267)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3