質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.21%

unsined charのポインタをstringのvectorでboostの共有メモリで格納し、子プロセスで戻したいが…

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,681

NEWBIEEBIEE

score 45

失礼します。質問内容が題名とかけ離れているようで申し訳ございません。
処理の流れとしてはカメラで撮ったcv::Matをunsined char化し、stringの動的配列として共有メモリに格納し、子プロセスでstringをイテレータで順次,unsigned char化してcv::Matに戻して再生したいです。

しかし、問題があり、

    vcap >> mat;

    MatToBytes(mat, &pBuf );
    std::string sName;
    myshmvector->push_back(sName(pBuf));、


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

二重ポインタのせいなのか、std::stringがbasic_stringに合わないのかわかりません。

どなたかご存じありませんか。どうかよろしくお願いします。

(自分はc++のことは全くわからないです)
(追記)
子プロセスのイテレータのも問題があるようで

      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);
      }


エラーでは
‘cv::Mat’ to ‘void*’ for argument ‘1’ to ‘void* memcpy(void*, const void*, size_t)’
std::memcpy(mat, pBuf, it->size());
が出力されます。
ごちゃごちゃしていてわからないと思いますが、ご教授の方お願いします。

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

#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;
}

12/24 19:08 Chironianさんの回答元に更新しました。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

こんにちは。

boostの共有メモリを使ったことはないので、見て分かる範囲で回答してみます。

sName(*pBuf)

はまずいです。*pBufはchar型です。char*型変数に*を付けているのでポインタではなくなっています。
そして、std::basic_string<>はchar型を受け取るコンストラクタを持たないです。

(unsigned char*)*it.c_str();

これは、下記のように書いてみて下さい。*演算子と.演算子では.演算子の方が優先順位が高かったと思います。

(unsigned char*)(*it).c_str();

後、↓もコンパイル・エラーにならないでしょうか?

std::memcpy(mat, pBuf, *it->size());

↓の間違いのような感じがします。

std::memcpy(mat, pBuf, it->size());

std::vector<T>のイテレータはT*型であるかのように振る舞います。
ですので、itはstd::basic_string<略>型へのポインタのように振る舞う筈です。


あああ、memcpyにcv::Mat型を直接与えることはできない筈です。
matに必要なメモリを獲得した上で、そこへコピーする必要が有ります。
memcpyよりもっと使い勝手の良いcv::Matのメンバ関数があるのでは?

std::memcpy(mat, pBuf, it->size());

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/12/24 18:47

    やってみます。

    キャンセル

  • 2016/12/24 19:03

    Chironianさん。有難うございます。もうちょっとご迷惑をおかけします。

    キャンセル

  • 2016/12/24 19:37

    cv::matのコンストラクタがあるようなのでそれやってみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.21%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる
  • トップ
  • C++に関する質問
  • unsined charのポインタをstringのvectorでboostの共有メモリで格納し、子プロセスで戻したいが…