如何在boost.interprocess共享内存中使用复杂结构的“push_back”函数向量

问题描述:

对不起,打扰你了。 我正在编写代码,使这个代码“http://coliru.stacked-crooked.com/a/0ab21481b69d87bb”在这个问题“Structures and vectors in Boost Shared Memory”,基础如何在boost.interprocess共享内存中使用复杂结构的“push_back”函数向量

但是,我被困在这一行的编译错误。

data.push_back(id); // 14 line in main function 

这个“data”val不匹配“push_back”函数。 此val由此行中的“auto &”声明。

auto& data = Shared::locate(smt); // 10 line in "while(1)" of main function 

(此定位(SMT)的功能是在共享存储器中的复杂的结构体的载体的构建体)

我假定“数据”是矢量或复杂结构的迭代器,但目前还没有办法运行我知道的这条线。

我不知道我在这段代码的某处出错了,但我不知道在哪里。

请帮帮我。

注1: 线 “data.push_back(ID);”对于boost :: container :: vector,boost :: interprocess :: iset_index>>,boost :: interprocess :: allocator,boost :: interprocess :: iset_index>>>,boost :: interprocess是没有匹配的函数:: segment_manager,升压::进程间:: iset_index>>> ::的push_back(INDATA &)” 候选:无效的boost ::容器::矢量::的push_back(常量Ť&)[用T = BasicInData,升压:: interprocess :: iset_index>>>; Allocator = boost :: interprocess :: allocator,boost :: interprocess :: iset_index>>>,boost :: interprocess :: segment_manager,boost :: interprocess :: iset_index >>] |

注2: 现在,我尝试改变下面的行;

cv::Mat_<cv::Vec3b> mat; 
cv::VideoCapture vcap(0); 

InData id(Shared::alloc<uchar_allocator>); 
    // camera open check 
if (!vcap.isOpened()) 
    return -1; 

但是,发生了另一个编译错误,“'id'是非类型的”。 我觉得缺乏一些东西。我该怎么做?

// opencv's lib  
#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 
// opencv's lib end 
#include <string> 
#include <boost/interprocess/managed_shared_memory.hpp> 

#include <boost/interprocess/managed_mapped_file.hpp> // use for Coliru 
#include <boost/interprocess/containers/vector.hpp> // boost/containers/vector.hpp 
#include <boost/interprocess/containers/string.hpp> // boost/containers/string.hpp 
#include <iostream> 
#include <sys/time.h> 
#include <stdio.h> 

//                 void_allocator; 
namespace bip = boost::interprocess; 

typedef unsigned char uchar; 
//Typedefs of allocators and containers 
typedef bip::managed_shared_memory::segment_manager      segment_manager_t; 
typedef bip::allocator<void, segment_manager_t> void_allocator; 

typedef void_allocator::rebind<uchar>::other       uchar_allocator; 
typedef bip::vector<uchar, uchar_allocator>         uchar_vector; 



template <typename Alloc = std::allocator<char> > 
struct BasicInData { 

    public: 
     BasicInData(Alloc alloc = {}) : image(alloc) 
     { } 

     template <typename T> 
     BasicInData(double x, int sizeImg, uchar_vector& image, Alloc alloc = {}) : 
      x(x), sizeImg(sizeImg), image(alloc) 
     { } 

     double x = 0; 
     int sizeImg = 0; 
     uchar_vector image; 
}; 

using InData = BasicInData<>; // just heap allocated 

namespace Shared { 
    using segment      = bip::managed_shared_memory; 
    using segment_manager    = segment::segment_manager; 

    template <typename T> using alloc = bip::allocator<T, segment_manager>; 
    template <typename T> using vector = bip::vector<T, alloc<T> >; 

    using InData = BasicInData<alloc<char> >; // shared memory version 

    vector<InData>& locate(segment& smt) { 
     auto* v = smt.find_or_construct<vector<InData> >("InDataVector")(smt.get_segment_manager()); 
     assert(v); 
     return *v; 
    } 
} 


int main(int argc, char* argv[]) { 
    if(argc == 1){ //Parent process 
     struct timeval tv; 
     // there are making no sense 2 line in below, just examine 
     gettimeofday(&tv, NULL); 
     double time = ((double)tv.tv_usec/1000000); 
     // Remove shared memory on construction and destruction 

     // Create a new segment with given name and size 
     struct shm_remove 
     { 
      shm_remove(){bip::shared_memory_object::remove("MySharedMemory");} 
      ~shm_remove(){bip::shared_memory_object::remove("MySharedMemory");} 
     }remover; 
     Shared::segment smt(bip::create_only,"MySharedMemory", 65536); // 65536 for coliru 
     auto& data = Shared::locate(smt); 
     //Shared::alloc bip::alloc_inst (data); 
     // Camera Capture 
     cv::Mat_<cv::Vec3b> mat; 
     cv::VideoCapture vcap(0); 

     InData id; 
     // camera open check 
     if (!vcap.isOpened()) 
      return -1; 

     while (1) { // while keyboard key push 
      vcap >> mat; // camera to mat 
      int image_size = mat.total() * mat.elemSize(); 
      id.sizeImg = image_size; 
      id.image.resize(image_size * sizeof(uchar)); 
      memcpy(&id.image[0], mat.data, image_size * sizeof(uchar)); 
      // get microsecond by double 
      gettimeofday(&tv, NULL); 
      double time = ((double)tv.tv_usec/1000000); 
      id.x = time; 
      data.push_back(id); 
      if(cv::waitKey(30) >= 0) break; // keyboard pushed 
     } 
     //Launch child process 
     std::string s(argv[0]); s += " child"; 
     if(0 != std::system(s.c_str())) 
      return 1; 

     // check child has destroyed the vector 
     if(segment.find<vector<InData>>("InDataVector").first) 
      return 1; 
     } 
    }else{ 
     // Open the managed segment 
     managed_shared_memory segment(open_only, "MySharedMemory"); 

     // Find the vector 
     vector<InData> *myvector = segment.find<vector<InData>>("InDataVector").first; 
     // Use vector in reverse order 

     vector<InData>::iterator it; 

     cv::Mat_<cv::Vec3b> im; 
     for(it = myvector->begin(); it !=myvector->end(); ++it){ 
      im.resize(it->sizeImg); 
      memcpy(im.data, &imref[0], it->sizeImg); 
      cv::imshow("window1", im); 
     } 

     segment.destroy<vector<InData>>("InDataVector"); 

     return 0; 
    } 
} 
+0

调试涉及'template'之外'auto'的问题的第一步是用您期望的类型替换'auto'(或'auto&')。 –

+0

谢谢你的回复,@ David Schmartz。请稍等一下。 – NEWBIEEBIEE

+0

现在,我将“auto&”替换为“Shared :: vector ”。编译器说“”矢量“不能转换为”int“。输出”int“的一部分在哪里?我不知道。 – NEWBIEEBIEE

我建议得到BasicInData(const BasicInData &data)BasicInData &operate =(const BasicInData &data)功能。

+0

谢谢您的回复。然后,我将不得不创建如功能? – NEWBIEEBIEE

谢谢大家的帮助。 最后我可以得到它。

在此行中的主要功能是

InData id; 

它被改变成

Shared::InData id(smt.get_segment_manager()); 

这是全码。

#include <cv.h> 
#include <cxcore.h> 
#include <highgui.h> 
#include <boost/interprocess/managed_shared_memory.hpp> 
#include <boost/interprocess/managed_mapped_file.hpp> // use for Coliru 
#include <boost/interprocess/containers/vector.hpp> // boost/containers/vector.hpp 
#include <boost/interprocess/containers/string.hpp> // boost/containers/string.hpp 
#include <iostream> 
#include <sys/time.h> 
#include <stdio.h> 

//                 void_allocator; 
namespace bip = boost::interprocess; 

typedef unsigned char uchar; 
//Typedefs of allocators and containers 
typedef bip::managed_shared_memory::segment_manager      segment_manager_t; 
typedef bip::allocator<void, segment_manager_t> void_allocator; 

typedef void_allocator::rebind<uchar>::other       uchar_allocator; 
typedef bip::vector<uchar, uchar_allocator>         uchar_vector; 



template <typename Alloc = std::allocator<uchar> > 
struct BasicInData { 

    public: 
     BasicInData(Alloc alloc = {}) : image(alloc) 
     { } 

     template <typename T> 
     BasicInData(double x, int sizeImg, uchar_vector& image, Alloc alloc = {}) : 
      x(x), sizeImg(sizeImg), image(alloc) 
     { } 

     double x = 0; 
     int sizeImg = 0; 
     uchar_vector image; 
}; 

using InData = BasicInData<>; // just heap allocated 

namespace Shared { 
    using segment      = bip::managed_shared_memory; 
    using segment_manager    = segment::segment_manager; 

    template <typename T> using alloc = bip::allocator<T, segment_manager>; 
    template <typename T> using vector = bip::vector<T, alloc<T> >; 

    using InData = BasicInData<alloc<uchar> >; // shared memory version 

    vector<InData>& locate(segment& smt) { 
     auto* v = smt.find_or_construct<vector<InData> >("InDataVector")(smt.get_segment_manager()); 
     assert(v); 
     return *v; 
    } 
} 


int main(int argc, char* argv[]) { 
    if(argc == 1){ //Parent process 
     // Remove shared memory on construction and destruction 

     // Create a new segment with given name and size 
     struct timeval tv; 
     gettimeofday(&tv, NULL); 
     struct shm_remove 
     { 
      shm_remove(){bip::shared_memory_object::remove("MySharedMemory");} 
      ~shm_remove(){bip::shared_memory_object::remove("MySharedMemory");} 
     }remover; 
     Shared::segment smt(bip::create_only,"MySharedMemory", 65536); // 10 Kb for coliru 
     auto &data = Shared::locate(smt); 
     //Shared::alloc bip::alloc_inst (data); 

     cv::Mat_<cv::Vec3b> mat; 
     cv::VideoCapture vcap(0); 

     Shared::InData id(smt.get_segment_manager()); 


     if (!vcap.isOpened()) 
      return -1; 

     while (1) { 
      vcap >> mat; 
      int image_size = mat.total() * mat.elemSize(); 
      id.sizeImg = image_size; 
      id.image.resize(image_size * sizeof(uchar)); 
      memcpy(&id.image[0], mat.data, image_size * sizeof(uchar)); 
      //Launch child process 
      gettimeofday(&tv, NULL); 
      double time = ((double)tv.tv_usec/1000000); 
      id.x = time; 
      data.push_back(id); 
      if(cv::waitKey(30) >= 0) break; 
     } 

     std::string s(argv[0]); s += " child"; 
     if(0 != std::system(s.c_str())) 
      return 1; 

     // check child has destroyed the vector 
     if(smt.find<Shared::vector<InData>>("InDataVector").first) 
      return 1; 

    } else{ 
     // Open the managed segment 
     bip::managed_shared_memory segment(bip::open_only, "MySharedMemory"); 

     // Find the vector using c-string name 
     bip::vector<InData> *myvector = segment.find<bip::vector<InData>>("InDataVector").first; 
     // Use vector in reverse order 

     bip::vector<InData>::iterator it; 

     cv::Mat_<cv::Vec3b> im; 
     for(it = myvector->begin(); it !=myvector->end(); ++it){ 
      im.resize(it->sizeImg); 
      memcpy(im.data, &it->image[0], it->sizeImg); 
      cv::imshow("window1", im); 
     } 

     segment.destroy<bip::vector<InData>>("InDataVector"); 

     return 0; 
    } 
}