C++/python共享内存交换图片/文本信息

共享内存保存读取图片

OpenShare.cpp

#include "OpenShare.h"

//共享内存1,, C++发 --python 传递位姿与图像存储路径
int key_id = 1111;
int shmid;
void *pBuffer;

//共享内存2, C++发 --python 传递位姿
int key_id2 = 6000;
int shmid2;
void *pBuffer2;

//共享内存3,python发 --C++ 传递图像
int key_id3 = 150;
int shmid3;
void *pBuffer3;

//共享内存初始化
bool InitOpenShare()
{
    //使用shmget()创建共享内存,该函数返回共享内存的标识符
    shmid = shmget((key_t)key_id, MEMORY_SIZE, 0666 | IPC_CREAT);
   
    if (-1 == shmid)
    {
        cout << "Created shared memory failed." << endl;
        return false;
    }
    //将共享内存连接到当前进程的地址空间
    //第一次创建完共享内存时,它还不能被任何进程访问
    //shmat()的作用就是启动对该共享内存的访问,并把共享内存链接到当前进程的地址空间
    pBuffer = shmat(shmid, 0, 0);
   
    if ((void *)-1 == pBuffer)
    {
        cout << "Shmat failed." << endl;
        return false;
    }

    //初始化共享内存全是0
    memset((char *)pBuffer, 0, MEMORY_SIZE);
    return true;
}


void WriteFlag2Share(char *Flag_Address, char value)
{
    memcpy(Flag_Address, &value, sizeof(value));
}

void ReadFlagFromShare(char *Flag_Address, char &value)
{
    memcpy(&value, Flag_Address, sizeof(value));
}

//向共享内存中发送Mat
void WriteMat2Share(char *MatHeadAddress, char *MatDataAddress, Mat image)
{
    MatHead MasterImgHead;
    MasterImgHead.width = image.cols;
    MasterImgHead.height = image.rows;
    MasterImgHead.type = image.type();

    //复制MatHead到共享内存中
    memcpy(MatHeadAddress, &MasterImgHead, sizeof(MatHead));

    //根据对8的余数计算出Mat元素占字节数
    int ByteNum = 1;
    switch (image.type() % 8)
    {
    default:
    case 0:
    case 1:
        ByteNum = 1;
        break;
    case 2:
    case 3:
        ByteNum = 2;
        break;
    case 4:
    case 5:
        ByteNum = 4;
        break;
    case 6:
        ByteNum = 8;
        break;
    }
    uint32_t address_bias = 0;

    for (uint32_t row = 0; row < image.rows; ++row)
    {
        address_bias = row * image.cols * image.channels() * ByteNum;
        memcpy(MatDataAddress + address_bias, image.ptr(row),
               image.cols * image.channels() * ByteNum);
    }
}

//接收Mat图像
Mat ReadMatFromShare(char *MatHeadAddress, char *MatDataAddress)
{
    MatHead MasterImgHead;
    Mat RMat;
    memcpy(&MasterImgHead, MatHeadAddress, sizeof(MatHead));

    //根据对8的余数计算出Mat元素占字节数
    int ByteNum = 1;
    switch (MasterImgHead.type % 8)
    {
    default:
    case 0:
    case 1:
        ByteNum = 1;
        break;
    case 2:
    case 3:
        ByteNum = 2;
        break;
    case 4:
    case 5:
        ByteNum = 4;
        break;
    case 6:
        ByteNum = 8;
        break;
    }
    RMat.create(MasterImgHead.height, MasterImgHead.width, MasterImgHead.type);
    uint32_t address_bias = 0;
    for (uint32_t row = 0; row < MasterImgHead.height; ++row)
    {
        address_bias = row * RMat.cols * RMat.channels() * ByteNum;
        memcpy(RMat.ptr(row), MatDataAddress + address_bias, RMat.cols * RMat.channels() * ByteNum);
    }

    return RMat;
}

//向共享内存中发送POSE Mat
void WritePose2Share(char *PoseHeadAddress, char *PoseDataAddress, Mat image)
{
    MatHead PoseHead;
    PoseHead.width = image.cols;
    PoseHead.height = image.rows;
    PoseHead.type = image.type();

    //复制PoseHead到共享内存中
    memcpy(PoseHeadAddress, &PoseHead, sizeof(MatHead));

    //根据对8的余数计算出Mat元素占字节数
    int ByteNum = 1;
    switch (image.type() % 8)
    {
    default:
    case 0:
    case 1:
        ByteNum = 1;
        break;
    case 2:
    case 3:
        ByteNum = 2;
        break;
    case 4:
    case 5:
        ByteNum = 4;
        break;
    case 6:
        ByteNum = 8;
        break;
    }
    uint32_t address_bias = 0;

    for (uint32_t row = 0; row < image.rows; ++row)
    {
        address_bias = row * image.cols * image.channels() * ByteNum;
        memcpy(PoseDataAddress + address_bias, image.ptr(row),
               image.cols * image.channels() * ByteNum);
    }
}

//接收Pose Mat
Mat ReadPoseFromShare(char *PoseHeadAddress,char *PoseDataAddress)
{
    MatHead PoseHead;
    Mat RMat;
    memcpy(&PoseHead, PoseHeadAddress, sizeof(MatHead));

    //根据对8的余数计算出Mat元素占字节数
    int ByteNum = 1;
    switch (PoseHead.type % 8)
    {
    default:
    case 0:
    case 1:
        ByteNum = 1;
        break;
    case 2:
    case 3:
        ByteNum = 2;
        break;
    case 4:
    case 5:
        ByteNum = 4;
        break;
    case 6:
        ByteNum = 8;
        break;
    }
    RMat.create(PoseHead.height, PoseHead.width, PoseHead.type);
    uint32_t address_bias = 0;
    for (uint32_t row = 0; row < PoseHead.height; ++row)
    {
        address_bias = row * RMat.cols * RMat.channels() * ByteNum;
        memcpy(RMat.ptr(row), PoseDataAddress + address_bias, RMat.cols * RMat.channels() * ByteNum);
    }

    return RMat;
}


//共享内存初始化
bool InitOpenShare2()
{
    //使用shmget()创建共享内存,该函数返回共享内存的标识符
    shmid2 = shmget((key_t)key_id2, MEMORY_SIZE2, 0666 | IPC_CREAT);
   
    if (-1 == shmid2)
    {
        cout << "shmid2: Created shared memory failed." << endl;
        return false;
    }
  
    pBuffer2 = shmat(shmid2, 0, 0);
   
    if ((void *)-1 == pBuffer2)
    {
        cout << "shmid2: Shmat failed." << endl;
        return false;
    }

    //初始化共享内存全是0
    memset((char *)pBuffer2, 0, MEMORY_SIZE2);
    return true;
}

void WriteFlag2Share2(char *Flag_Address, char value)
{
    memcpy(Flag_Address, &value, sizeof(value));
}

void ReadFlagFromShare2(char *Flag_Address, char &value)
{
    memcpy(&value, Flag_Address, sizeof(value));
}


void WriteString2Share(char* ImagePathAddress, std::string str)
{
	memcpy(ImagePathAddress, str.data(), str.length());
}

std::string ReadStringFromShare(char* ImagePathAddress, const int ImagePathLength) {
	char path[ImagePathLength];
	strncpy(path, ImagePathAddress, ImagePathLength);
	return path;
}

//
//共享内存3初始化
bool InitOpenShare3()
{
    //使用shmget()创建共享内存,该函数返回共享内存的标识符
    shmid3 = shmget((key_t)key_id3, MEMORY_SIZE3, 0666 | IPC_CREAT);
   
    if (-1 == shmid3)//
    {
        cout << "shmid3: Created shared memory failed." << endl;
        return false;
    }
    else
    {
        //cout << "共享内存3初始化成功"<<endl;
    }
    
    //将共享内存连接到当前进程的地址空间
    //第一次创建完共享内存时,它还不能被任何进程访问
    //shmat()的作用就是启动对该共享内存的访问,并把共享内存链接到当前进程的地址空间
    pBuffer3 = shmat(shmid3, 0, 0);
   
    if (pBuffer3 == (void*)-1)
    {
        cout << "shmid3:Shmat failed." << endl;
        return false;
    }

    //初始化共享内存全是0
    memset(pBuffer3, 0, MEMORY_SIZE3);
    return true;
}

//从共享内存读取图像数据(python)
cv::Mat ReadImageFromShare() {

            image_head image_dumper;
            memcpy(&image_dumper, IMAGE_ADDRESS3, sizeof(image_head));

            //std::cout<<image_dumper.rows<<"  "<<image_dumper.cols<<std::endl;

            uchar* data_raw_image = image_dumper.dataPointer;

            cv::Mat image(image_dumper.rows, image_dumper.cols, CV_8UC3);

            uchar* pxvec = image.ptr<uchar>(0);
            int count = 0;
            for (int row = 0; row < image_dumper.rows; row++) {
                pxvec = image.ptr<uchar>(row);
                for (int col = 0; col < image_dumper.cols; col++) {
                    for (int c = 0; c < 3; c++) {
                        pxvec[col * 3 + c] = data_raw_image[count];
                        count++;
                    }
                }
            }
            return image;
}
// //向共享内存中发送位置
// void WritePosition2Share(char *PositionAddress,Position posoition_xyz)
// {
//    memcpy(PositionAddress, &posoition_xyz, sizeof(Position));
// }

OpenShare.h

#ifndef _OPENSHARE_H
#define _OPENSHARE_H

#include <opencv2/opencv.hpp>
#include <iostream>
#include <sys/shm.h>
#include <stdlib.h>

using namespace std;
using namespace cv;

//Mat头部定义
typedef struct
{
    int width;
    int height;
    int type;
} MatHead;

typedef struct
 {
   double x;
   double y;
   double z;
 } Position;

 //图像
 #define image_size_max 1920*1080*3
typedef struct {
    int rows;
    int cols;
    uchar dataPointer[image_size_max];
} image_head;

extern int key_id;
extern int shmid;
extern void *pBuffer;

extern int key_id2;
extern int shmid2;
extern void *pBuffer2;

extern int key_id3;
extern int shmid3;
extern void *pBuffer3;

bool InitOpenShare();
bool InitOpenShare2();
bool InitOpenShare3();

void WriteFlag2Share(char *Flag_Address, char value);
void ReadFlagFromShare(char *Flag_Address, char &value);

void WriteMat2Share(char *MatHeadAddress, char *MatDataAddress, Mat image);
Mat ReadMatFromShare(char *MatHeadAddress, char *MatDataAddress);

void WritePose2Share(char *PoseHeadAddress,char *PoseDataAddress, Mat image);
Mat ReadPoseFromShare(char *PoseHeadAddress,char *PoseDataAddress);

void WriteFlag2Share2(char *Flag_Address, char value);
void ReadFlagFromShare2(char *Flag_Address, char &value);
//void WritePosition2Share(char *PositionAddress,Position posoition_xyz);

void WriteString2Share(char* ImagePathAddress, std::string str);
std::string ReadStringFromShare(char* ImagePathAddress, const int ImagePathLength);
//从共享内存读图片
cv::Mat ReadImageFromShare();

//共享内存1:

//将SLAM的pose与图像存储路径传到共享内存,共享内存各个块的size
#define FLAG_SIZE                   10UL                               //预留FLAG大小为100byte
#define MAT_SIZE                    1920 * 1080 * 3 * 8UL               //预留Mat大小 1920*1080*3 CV_64F
#define MATHEAD_SIZE                sizeof(MatHead)                     //头部大小
#define Pose_MAT_ZIZE               4*4*sizeof(double)  //数据大小定义
//共享内存的大小
#define MEMORY_SIZE                 MAT_SIZE * 10
// 定义字符串的长度
#define IMAGE_PATH_SIZE             1024

//共享内存1:各部分头地址
#define MEMORY_ADDRESS            (char *)pBuffer
#define FLAG_ADDRESS              MEMORY_ADDRESS + 1                    
#define POSEMAT_HEAD_ADDRESS      FLAG_ADDRESS + 1 
#define POSEMAT_DATA_ADDRESS      POSEMAT_HEAD_ADDRESS + MATHEAD_SIZE
//
#define CURRENT_FRAME_HEAD        POSEMAT_DATA_ADDRESS + Pose_MAT_ZIZE
#define CURRENT_FRAME_DATA        CURRENT_FRAME_HEAD + MATHEAD_SIZE
#define IMAGE_PATH_ADDRESS        CURRENT_FRAME_DATA + IMAGE_PATH_SIZE

//共享内存2:
//将SLAM的pose传到共享内存,共享内存各个块的size
#define MEMORY_SIZE2   4 * 4 * sizeof(double)+ sizeof(MatHead)+1 //预留Mat大小 

#define PoseMATHEAD_SIZE2                sizeof(MatHead)                     //头部大小
#define Pose_MAT_ZIZE2               4*4*sizeof(double)  //数据大小定义

//共享内存2:各部分头地址
#define MEMORY_ADDRESS2 (char *)pBuffer2
#define FLAG_ADDRESS2 MEMORY_ADDRESS2 + 1
#define POSEMATHEAD_ADDRESS2 FLAG_ADDRESS2 + 1
#define POSEMAT_ADDRESS2 POSEMATHEAD_ADDRESS2 + PoseMATHEAD_SIZE2
#endif

//共享内存3:
//从共享内存取图像
//共享内存的大小
#define MEMORY_SIZE3                 image_size_max * 10
//共享内存3:各部分头地址
#define MEMORY_ADDRESS3            (char *)pBuffer3
#define FLAG_ADDRESS3 MEMORY_ADDRESS3+1
#define IMAGE_ADDRESS3 FLAG_ADDRESS3+1

动态链接库 lib.cpp

#include "OpenShare.h"
//生成的.so文件用于parrot读取SLAM位姿
extern "C"
{
    int initOpenShare() {
        return InitOpenShare2();//这里对应的是共享内存2,Key_id2,从共享内存2中读取Pose
    }
    // 标志位
    void writeFlag2OpenShare(char value) {
        WriteFlag2Share(FLAG_ADDRESS2, value);//从共享内存2中写入flag
    }
    char readFlagFromOpenShare() {
        char ch;
        ReadFlagFromShare(FLAG_ADDRESS2, ch);//从共享内存2中读取flag
        return ch;
    }

    // 读取字符串
    char* readImagePathFromOpenShare() {
        char *path = (char*)malloc(sizeof(char) * IMAGE_PATH_SIZE);
        std::string image_path = ReadStringFromShare(IMAGE_PATH_ADDRESS, IMAGE_PATH_SIZE);
        //std::cout << "image_path = \n" << image_path << std::endl;
        strcpy(path,image_path.c_str());
        //strncpy(path, image_path.data(), image_path.length());
        //printf("xxxxxxxx%s\n",path);
        return path;
    //    std::string image_path = ReadStringFromShare(IMAGE_PATH_ADDRESS, IMAGE_PATH_SIZE);
    //     return const_cast<char*>(image_path.c_str()); 
    }

    // 读取图像
    uchar* readImageFromOpenShare() {
        cv::Mat image = ReadMatFromShare(CURRENT_FRAME_HEAD, CURRENT_FRAME_DATA);
        int rows = image.rows;
        int cols = image.cols;
        int channels = image.channels();
        // printf("rows = %d cols = %d channels = %d size = %d\n", rows, cols, channels, rows*cols*channels);
        uchar *data = (uchar*)malloc(sizeof(uchar) * rows * cols * channels);
        uchar *p = data;
        
        // if(image.isContinuous()) {
        //     cols *= rows;
        //     rows = 1;
        // }
        // for(int r = 0; r < rows; r++) {
        //     uchar *img_data = image.ptr<uchar>(r);
        //     for(int c = 0; c < cols; c++) {
        //         *(p++) = img_data[0];
        //         *(p++) = img_data[1];
        //         *(p++) = img_data[2];
        //         img_data += 3;
        //     }
        // }
        // 也可以直接使用内存拷贝的方式
        memcpy(data, image.data, rows * cols * channels);
        return data;
    }

    double* readPoseFromShareMemory() {
        cv::Mat pose = ReadMatFromShare(POSEMATHEAD_ADDRESS2, POSEMAT_ADDRESS2);
        //std::cout << "c++ pose = \n" << pose << std::endl; 
        double *data = (double*)malloc(sizeof(double) * pose.rows * pose.cols);
        memcpy(data, pose.data, sizeof(double) * pose.rows * pose.cols);
        return data;
    }

    // 释放内存
    void freeMemory(void* data) {
        free(data);
    }
}


cmake

# cmake needs this line
cmake_minimum_required(VERSION 2.8)

# Define project name
project(read_pose)

# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)

# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

if(CMAKE_VERSION VERSION_LESS "2.8.11")
  # Add OpenCV headers location to your include paths
  include_directories(${OpenCV_INCLUDE_DIRS})
endif()

# Declare the executable target built from your sources
add_library(read_pose SHARED PyCall2.cpp OpenShare.cpp)


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


python调用

#-- coding:UTF-8 --
import sys

import ctypes
import numpy as np
import cv2
import time
import threading
from threading import Lock,Thread

lock = Lock()
posecw = np.zeros((4,4),dtype=np.float64)

class LoadLibrary(object):
    def __init__(self, lib_path):
        self._lib_path = lib_path
        # 加载动态库
        self._libObj = ctypes.cdll.LoadLibrary(self._lib_path)
        # 导出动态库中所有的函数
        # c中的函数接口: int initOpenShare()
        self._initShareMemory = self._libObj.initOpenShare
        self._initShareMemory.restype = ctypes.c_int
        # c中的函数接口: char readFlagFromOpenShare()
        self._readFlagFromShareMemory = self._libObj.readFlagFromOpenShare
        self._readFlagFromShareMemory.restype = ctypes.c_char
        # c中的函数接口: void writeFlag2OpenShare(char value)
        self._writeFlag2ShareMemory = self._libObj.writeFlag2OpenShare
        self._writeFlag2ShareMemory.argtype = (ctypes.c_char)
        # c中的函数接口: double* readPoseFromShareMemory() 
        self._readPoseFromShareMemory = self._libObj.readPoseFromShareMemory
        self._readPoseFromShareMemory.restype = ctypes.POINTER(ctypes.c_double)
        # c中的函数接口: void freeMemory(uchar* data)
        self._freeMemory = self._libObj.freeMemory
        self._freeMemory.argtype = (ctypes.POINTER(ctypes.c_void_p))

    # 初始化共享内存
    def initShareMem(self):
        res = self._initShareMemory()
        return res

    # 从共享内存中读取标志位
    def readFlag(self):
        flag = self._readFlagFromShareMemory()
        # python中bytes与int之间的转换参考
        # https://www.delftstack.com/zh/howto/python/how-to-convert-bytes-to-integers/
        return int.from_bytes(flag, byteorder='big')

    # 改变共享内存中的标志位
    def writeFlag(self, pyFlag):
        flag = ctypes.c_char(pyFlag)
        self._writeFlag2ShareMemory(flag)

    # 读取pose
    def readPose(self, size=(4,4,1)):
        ptr = self._readPoseFromShareMemory()
        pose = np.reshape(np.array(np.fromiter(ptr, np.float64, size[0]*size[1]*size[2])), size)
        return ptr, pose

    # 释放内存
    def freeMemory(self, ptr):
        self._freeMemory(ptr)


def Get_position():
         while True:
             time.sleep(0.01)
             flag = libObj.readFlag()
             print(flag)
             if not flag:
                 continue
             global posecw
             lock.acquire()
             ptr2, pose = libObj.readPose()
             libObj.freeMemory(ptr2)
             posecw = pose
             print('---------------------------------------------------')
             print('pose = \n', pose)
             libObj.writeFlag(0)        
             lock.release()



if __name__ == '__main__':
    lib_path = "./build/libread_pose.so"
    libObj = LoadLibrary(lib_path)
    libObj.initShareMem()
    t1 = threading.Thread(target=Get_position)
    t1.setDaemon(True)  
    t1.start()
    while True:
        time.sleep(0.02)
        posecw
        lock.acquire()
        current_Posematcw = posecw
        print("current_Posematcw: ",current_Posematcw)#4*4 
        #current_Posematwc = np.linalg.pinv(current_Posematcw)
        #print("current_Posematwc: ",current_Posematwc) #相机到世界的位置
        # try:
        #   current_Posematwc = np.linalg.inv(current_Posematcw)
        #   print("current_Posematwc: ",current_Posematwc)
        # except:
        #  print("矩阵不存在逆矩阵")
        lock.release()

c++测试接收图片

#include <iostream>
#include <stdlib.h>
#include <sys/shm.h>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/videoio.hpp"

#define key 650
#define image_size_max 1920*1080*3

using namespace cv;
using namespace std;

typedef struct{
int rows;
int cols;
uchar dataPointer[image_size_max];
}image_head;

int main()
{
  int count = 1;
  while(true)
  {

    int shm_id = shmget(key,sizeof(image_head) ,IPC_CREAT);
    if(shm_id == -1)
     {
        cout<<"shmget error"<<endl;
	  return -1;
     }
    cout << " shem id is  "<<shm_id<<endl;

    image_head* buffer_head;
    buffer_head = (image_head*)shmat(shm_id, NULL, 0);
    
    if((long)buffer_head == -1)
    {
        perror("Share memary can't get pointer\n");  
          return -1;  
    }

    image_head image_dumper;
    memcpy(&image_dumper, buffer_head, sizeof(image_head));
    cout<<image_dumper.rows<<"  "<<image_dumper.cols<<endl;

    uchar* data_raw_image=image_dumper.dataPointer;

    cv::Mat image(image_dumper.rows, image_dumper.cols, CV_8UC3);
    uchar* pxvec =image.ptr<uchar>(0);
    int count = 0;
    for (int row = 0; row < image_dumper.rows; row++)
    {
      pxvec = image.ptr<uchar>(row);
      for(int col = 0; col < image_dumper.cols; col++)
      {
        for(int c = 0; c < 3; c++)
        {
          pxvec[col*3+c] = data_raw_image[count];
          count++;
        }
      }
    }
   shmdt(buffer_head);
   cv::imshow("Win",image);
   cv::waitKey(1);

  }

   return 1;
}

共享内存交换文本信息

动态链接库 gps_so.cpp

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sys/shm.h>
#include <unistd.h>
#include <sstream>
#include <iomanip> 
using namespace std;

#define key 783
#define cam_num 0


char* dump()
{
  int shm_id = shmget(key+cam_num, sizeof(int)*3, IPC_CREAT);
  cout << " shem id is  "<< shm_id <<endl;
  static char *buffer_head;
  
  buffer_head = (char*)shmat(shm_id, NULL, 0);

  
  //printf("rec_buff_addr: %p \n", buffer_head);
  //printf("rec_buff_str: %s \n", buffer_head);
  //printf("rec_buff_size: %d \n", (int)(strlen(buffer_head)+1));
  
  char *gps_dunper = new char[strlen(buffer_head)+1];
  strcpy(gps_dunper, buffer_head);


  usleep(10000);

  return gps_dunper;
}


extern "C"
{
  char* dump_()
  {
    char* result=dump();
    return result;
  }
}

c++发送和读取

发送 write.cpp

#include <stdio.h>
#include <string.h>
#include <sys/shm.h>
#include <iostream>
#include <unistd.h>
#include <sstream>
#include <iomanip>
using namespace std;

#define key 753
#define cam_num 0

int main(void)
{
    while(true){
    
        int shm_id = shmget(key+cam_num, sizeof(int)*3, IPC_CREAT);
        cout << " shem id is  "<< shm_id <<endl;
        if(shm_id == -1)
        {
            cout<<"shmget error"<<endl;
            return -1;
        }
        cout << " shem id is  "<< shm_id <<endl;

        static char *buffer_head;
        buffer_head = (char*)shmat(shm_id, NULL, 0);
        if((long)buffer_head == -1)
        {
            cout<<"Share memary can't get pointer"<<endl; 
            return -1; 
        }

        double n1 = 4.7634929291647467e+01;
        double n2 = -1.2213964522700627e+02;
        double n3 = 1.5723567199707031e+02;
        stringstream ss1, ss2, ss3;

	//保留小数点后12位
        ss1<<fixed<<setprecision(12)<<n1;
        ss2<<fixed<<setprecision(12)<<n2;
        ss3<<fixed<<setprecision(12)<<n3;
        std::string s1 = ss1.str();
        std::string s2 = ss2.str();
        std::string s3 = ss3.str();

	//字符串拼接
        std::string s = s1+'|'+s2+'|'+s3;
        std::cout<< "s:"<<s<<std::endl;

	
        int size_s = strlen(s.c_str())+1;
        static char* strc = new char[size_s];
        cout<<"size: "<< size_s <<std::endl;
        strcpy(strc, s.c_str());
        // printf("strc: %s \n", strc);
	
	//写到内存
        strcpy(buffer_head, s.c_str());
        
        printf("buff_str: %s \n", buffer_head);
        //10000微妙,10毫秒
        usleep(10000);
        shmdt(buffer_head);   //释放内存,没测试
    }
    //释放共享内存块
    //shmctl(shm_id, IPC_RMID, 0);
    return 0;
}

c++读取read.cpp

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <sys/shm.h>
#include <unistd.h>

using namespace std;

#define key 753
#define cam_num 0

char* dump(int cam_num1)
{
  int shm_id = shmget(key+cam_num, sizeof(int)*3, IPC_CREAT);
    
  char *buffer_head;
  buffer_head = (char*)shmat(shm_id, NULL, 0);
  std::string buff_str = buffer_head;
  printf("rec_buff_str_addr: %p \n", buffer_head);
  printf("rec_buff_str: %s \n", buffer_head);
  printf("rec_buff_str: %d \n", (int)(strlen(buffer_head)+1));

  usleep(10000);

  return buffer_head;
}


int main(void)
{
    while(true){
        char* res = dump(0);
        usleep(10000); 
        
    }
    //shmctl(segment_id, IPC_RMID, 0);
    return 0;
}

cmake

# cmake needs this line
cmake_minimum_required(VERSION 2.8)
 
# Define project name
project(opencv_example_project)
 
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
#find_package(OpenCV REQUIRED)
 
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them

#message(STATUS "OpenCV library status:")
#message(STATUS "    version: ${OpenCV_VERSION}")
#message(STATUS "    libraries: ${OpenCV_LIBS}")
#message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
 
if(CMAKE_VERSION VERSION_LESS "2.8.11")
  # Add OpenCV headers location to your include paths
  #include_directories(${OpenCV_INCLUDE_DIRS})
endif()
 
# Declare the executable target built from your sources
add_library(gps_example  SHARED gps_so.cpp)
add_library(imgflag_example  SHARED imgflag_so.cpp)
add_executable(write_run write.cpp)
add_executable(read_run read.cpp)
add_executable(img_write write_flag.cpp)
add_executable(img_read read_flag.cpp)
 
# Link your application with OpenCV libraries
#target_link_libraries(opencv_example ${OpenCV_LIBS})
#target_link_libraries(test_example ${OpenCV_LIBS})

python 读取和发送

python 读取

#!/usr/bin/env python
 
import sys
 
import cv2
from ctypes import *
# import ctypes
import types
import numpy as np
# ll = ctypes.cdll.LoadLibrary
# ll = ctypes.cdll.LoadLibrary
# lib = ll("./build/libopencv_example.so")
lib = CDLL("./build/libgps_example.so") 
lib.dump_.restype = c_char_p   #class ctypes.Structure(*args, **kw)¶
 

gps = lib.dump_()
print(len(gps))
print("rec_py", gps, type(gps))

rec = str(gps, encoding='utf-8')
print(rec, type(rec))
rec_list = rec.split("|")
print(rec_list, type(rec_list))
num = []
i = 0
for s in rec_list[:]:
  num.append(float(s))
  print(num[i], type(num[i]))
  i+=1
  


# count = 0

 
# while count < 10:
#     # path = "./image/"+str(count).zfill(4)+".png"
#     # print(path)
#     # image=cv2.imread(path)
     
#     # #cv2.imshow("test",image)
#     # #cv2.waitKey(0)
 
#     # image_data = np.asarray(image, dtype=np.uint8)
#     # image_data = image_data.ctypes.data_as(ctypes.c_void_p)
 
#     value = lib.dump_(0)
#     print(value)
 
#     count += 1
 
#     # if count == 494:
#     #     count = 0
 

原文链接: https://www.cnblogs.com/xiaohuidi/p/17020526.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++/python共享内存交换图片/文本信息

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/309076

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月16日 上午10:50
下一篇 2023年2月16日 上午10:50

相关推荐