首页 > 系统相关 >C++/python共享内存交换图片/文本信息

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

时间:2023-01-02 21:26:53浏览次数:50  
标签:include python image C++ char int 共享内存 define

共享内存保存读取图片

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
 

标签:include,python,image,C++,char,int,共享内存,define
From: https://www.cnblogs.com/xiaohuidi/p/17020526.html

相关文章

  • 用python爬取网络文章----滴天髓
    用python爬取网络文章真的很简单。主要分以下几个步骤1、安装并导入相关模块.这里我们要用到两个模块,分别是reqesets和lxml安装命令pipinstallrequests和pipinstall......
  • python+Django学习资源汇总-更新中
    ​​Python教程​​​​Python3.7.4文档​​​​Python基础教程​​​​Python教程​​​​Python入门​​ ​​python+django搭建web项目​​​​PythonDjango(WEB电......
  • 2D Pose人体关键点实时检测(Python/Android /C++ Demo)
    2DPose人体关键点实时检测(Python/Android/C++Demo)目录​​2DPose人体关键点实时检测(Python/Android/C++Demo)​​​​1.人体关键点数据集​​​​(1)COCO数据集​​......
  • 双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python
    双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python目录​​双目三维重建系统(双目标定+立体校正+双目测距+点云显示)Python​​​​1.项目结构​​​​2.Envir......
  • C++ | 3-需要函数对象的容器
    函数对象及其特化首先来讨论一下两个重要的函数对象,less和hash。们先看一下less,小于关系。在标准库里,通用的less大致是这样定义的:template<classT>structless......
  • django与python版本对应关系 附加djangorestframework框架
    Django与python版本Django1.11版本兼容Python2.7、3.4、3.5、3.6、3.7(addedin1.11.17)#1.11.5python<=3.6Django2.0版本兼容Python3.4、3.5、3.6、3.7Djang......
  • python 使用 VSCode 入门简介
    本文主要介绍如何使用VSCode创建、编辑、运行、调试hello.py程序,对如何安装使用python不做介绍,也不对安装vscode介绍。准备事项电脑安装python3,vscode,并安装v......
  • Python pip3用国内源安装
    国内可用的源如下:清华:https://pypi.tuna.tsinghua.edu.cn/simple中国科技大学https://pypi.mirrors.ustc.edu.cn/simple/华中理工大学:http://pypi.hustunique.com/山东理工......
  • 【C++高级编程】(三)面向对象设计
    本章内容:什么是面向对象的程序设计如何定义不同对象之间的关系抽象的重要性以及如何在设计中使用抽象()  3.1过程化的思考方式    3.2面向对象思想......
  • 【C++入门】(九)位运算与常用库函数
    一.位运算符号运算&与|或~非^异或>>右移<<左移常用操作:求x的第k位数字x>>k&1lowbit(x)=x&-x,返回x的最后一位1 二.......