31404


別のサイトで同じような質問をさせて頂きました。

処理の流れとしてはカメラで撮ったcv::Matをunsined
char化し、stringの動的配列として共有メモリに格納し、子プロセスでstringをイテレータで順次，unsigned
char化してcv::Matに戻して再生したいです。

しかし、問題があり、

[code]

    vcap >> mat;
    
    MatToBytes(mat, &pBuf );
    std::string sName;
    myshmvector->push_back(sName(pBuf));、
    
[/code]

というコードで、MatToBytesにMatと pBufというunsigned charの二重ポインタを引数でとり、格納し、memcpyしたいのですが、  
共有メモリのVectorにてStringで格納する際、  
コンパイルエラーでno match for call to ‘(std::string {aka std::basic_string})
(uchar*&)’  
myshmvector->push_back(sName(pBuf));

pBufのucharがbasic_stringにどうしても合わないようです。

子プロセスのイテレータのも問題があるようで

[code]

      MyShmStringVector::iterator it;
      cv::Mat mat;
      cv::VideoCapture vcap(0);
      uchar* pBuf = NULL;
    
      for(it = myvector->begin(); it !=myvector->end(); ++it){
            pBuf = (unsigned char*)(*it).c_str();
            std::memcpy(mat, pBuf, it->size());
            cv::imshow("window1", mat);
      }
    
[/code]

エラーでは

[code]

    cv::Mat’ to ‘void*’ for argument ‘1’ to ‘void* memcpy(void*, const void*, size_t)’
        std::memcpy(mat, pBuf, it->size());
    
[/code]

が出力されます。  
ご教授の方お願いします。

全体のコードになります。（解りずらいと思いますが、説明下手と状況把握が不十分なので）

[code]

    #include <boost/interprocess/managed_shared_memory.hpp>
    #include <boost/interprocess/containers/vector.hpp>
    #include <boost/interprocess/containers/string.hpp>
    #include <boost/interprocess/allocators/allocator.hpp>
    #include <string>
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <cstdlib> // std::system
    
    using namespace boost::interprocess;
    
    typedef unsigned char uchar;
    
    typedef allocator<char, managed_shared_memory::segment_manager> CharAllocator;
    
    typedef basic_string<char, std::char_traits<char>, CharAllocator> MyShmString;
    
    typedef allocator<MyShmString, managed_shared_memory::segment_manager> StringAllocator;
    
    typedef vector<MyShmString, StringAllocator> MyShmStringVector;
    
    int MatToBytes(cv::Mat image, uchar ** pimage_uchar)
    {
        uchar * image_uchar = * pimage_uchar;
        // class data members of ints
        int image_rows = image.rows;
        int image_cols = image.cols;
        int image_type = image.type();
    
        int image_size = image.total() * image.elemSize();
        image_uchar = new uchar[image_size];
        std::memcpy(image_uchar, image.data, image_size * sizeof(uchar));
        return 1;
    }
    
    int main(int argc, char* argv[])
    {
    
        struct shm_remove
        {
            shm_remove(){shared_memory_object::remove("MySharedMemory");}
            ~shm_remove(){shared_memory_object::remove("MySharedMemory");}
        }remover;
    
    
        if(argc == 1){ //Parent process
            // Remove shared memory on construction and destruction
    
        // Create a new segment with given name and size
        managed_shared_memory segment(create_only,"MySharedMemory",65536);
    
        //Initialize shared memory STL-compatible allocator
        CharAllocator charallocator(segment.get_segment_manager());
        StringAllocator stringallocator(segment.get_segment_manager());
        //Construct a vector named "MyVector" in shared memory with argument alloc_inst
        MyShmStringVector *myshmvector = segment.construct<MyShmStringVector>("MyVector")(stringallocator);
    
    
        cv::Mat InputImage;
        cv::Mat mat;
        cv::VideoCapture vcap(0);
        uchar* pBuf = NULL;
    
    
        if (!vcap.isOpened())
            return -1;
    
        while (1) {
            vcap >> mat;
    
            MatToBytes(mat, &pBuf );
            std::string sName;
            myshmvector->push_back(sName(pBuf));
            //Launch child process
            if(cv::waitKey(30) >= 0) break;
        }
        // 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<MyShmStringVector>("MyVector").first)
            return 1;
        }
        else{// child process
            // Open the managed segment
            managed_shared_memory segment(open_only, "MySharedMemory");
    
            // Find the vector using c-string name
            MyShmStringVector *myvector = segment.find<MyShmStringVector>("MyVector").first;
    
            // Use vector in reverse order
    
            MyShmStringVector::iterator it;
            cv::Mat mat;
            cv::VideoCapture vcap(0);
            uchar* pBuf = NULL;
    
            for(it = myvector->begin(); it !=myvector->end(); ++it){
                pBuf = (unsigned char*)(*it).c_str();
                std::memcpy(mat, pBuf, it->size());
                cv::imshow("window1", mat);
            }
    
            segment.destroy<MyShmStringVector>("MyVector");
    
        }
        return 0;
    }
    
[/code]


CC BY-SA 3.0
2016-12-24T07:33:01.837
31351
2016-12-26T06:36:32.350
2016-12-24T12:57:05.877
19922
19922
question
c++ opencv boost ポインタ メモリ管理
boost::interprocessのvector内のbasic_stringへのchar*からの変換


コードのこの部分を落ち着いてよく見てみてください．

[code]

    MatToBytes(mat, &pBuf );
    std::string sName;
    ... sName(pBuf) ...
    
[/code]

`sName`は関数ではなく`std::string`型のオブジェクトです．エラーメッセージの言うように`std::string`クラスには`operator()(uchar*)`が定義されていないので`sName(pBuf)`という風に関数呼び出しのような形で用いることはできません．

子プロセスのイテレータの問題についても落ち着いてよく見てみてください，

[code]

      cv::Mat mat;
    ...
            std::memcpy(mat, pBuf, it->size());
    ...
    
[/code]

エラーメッセージの言うように`std::memcpy`関数は第一引数に`void*`を取るのに，コードでは`void*`に暗黙変換できない`cv::Mat`オブジェクトを渡しています．

やっていることの複雑さに囚われずに，落ち着いてエラーメッセージを読みましょう．


CC BY-SA 3.0
2016-12-26T06:36:32.350
31404
2016-12-26T06:36:32.350
4548
31351
answer