

OpenCVのMatデータ、またはVectorデータを共有メモリに渡す方法が分からず困っています。  
ポインターの使い方の理解不足かもしれませんが、アドバイス頂ければとても有難いです。

boost/interprocess/managed_shared_memoryを使ってMatのデータを共有メモリ上に保存して別のプロセスに渡したいと思い、下記のようにして渡したところassignの中で落ちてしまいます。  
エラー等は一切出ませんでした。

[code]

    managed_shared_memory shmd(create_only, DEPTHNAME, WIDTH_PIC * HEIGHT_PIC * 4 + 1024);
    
    interprocess_mutex* mxd = shmd.construct<interprocess_mutex>("TheMutex")();
    
    std::vector<float> *ptrd=shmd.construct< std::vector<float> >("DepthImage")(); 
    //ロック
    mxd->lock(); 
    //共有メモリに書き込み
    ptrd->assign((float*)decodedDepthData2.datastart,(float*)decodedDepthData2.dataend);
    //ロックを解除
    mxd->unlock();
    
[/code]

※cv::Mat decodedDepthDataはCV_32FC1の横：WIDTH_PIC 縦：HEIGHT_PICの深度画像です。

ポインタ型にしなければコピーできるようで

下記のようにしてvector型の変数に値を入れることができています。

* * *
[code]

    cv::Mat M=Mat(480,480,CV_32FC1,「the data ....」);   
    
    //copy vector to mat   
    
    vector< float> Vf2;   
    
    //copy mat to vector   
    
    Vf2.assign((float*)M.datastart, (float*)M.dataend);   
    
[/code]

* * *

しかし、下記のようにポインタ型のvector変数にコピーしようとした場合  
最初に書いたshared memoryと同じようにAssignの途中でエラーも吐かずに落ちてしまいます。

* * *
[code]

    cv::Mat M=Mat(480,480,CV_32FC1,「the data ....」);   
    
    //copy vector to mat   
    
    vector< float> *Vf2;   
    
    //copy mat to vector   
    
    Vf2->assign((float*)M.datastart, (float*)M.dataend);  
    
[/code]

* * *

shared memoryにMatのデータを渡してやるにはどうすればよいでしょうか？

どなたかアドバイス下さい。


CC BY-SA 3.0
2015-08-19T17:00:17.237
14637
2015-08-19T22:05:22.407
2015-08-19T21:46:31.333
4236
10994
question
c++ opencv ポインタ boost stl
Matデータ(or Vectorデータ)を共有メモリに渡す方法


`std::vector<float>` と指定されていますが、デフォルトテンプレート引数により正確には `std::vector< float,
std::allocator<float> >` となっています。  
これの意味するところは、vectorの管理領域（size情報など）は共有メモリに確保されますが実データ（float配列）はstd::allocatorから確保されるため共有メモリとはなりません。

Boost.Interprocessが提供する`Allocator`を指定する必要があります。boost/interprocess/containers/vector.hppを使ってはいますが、[Creating
vectors in shared
memory](http://www.boost.org/doc/libs/1_59_0/doc/html/interprocess/quick_guide.html#interprocess.quick_guide.qg_interprocess_container)にそのままのサンプルがあります。

[code]

    typedef allocator<float, managed_shared_memory::segment_manager> ShmemAllocator;
    typedef vector<float, ShmemAllocator> MyVector;
    
    const ShmemAllocator alloc_inst(shmd.get_segment_manager());
    MyVector* ptrd = shmd.construct<MyVector>("DepthImage")(alloc_inst);
    
[/code]


CC BY-SA 3.0
2015-08-19T21:45:37.973
14640
2015-08-19T21:45:37.973
4236
14637
answer

[code]

    vector< float> *Vf2;   
    Vf2->assign((float*)M.datastart, (float*)M.dataend);  
    
[/code]

未初期化のポインタだけあっても何の役にも立たないので落ちて当然。

[code]

    std::vector<float> *ptrd=shmd.construct< std::vector<float> >("DepthImage")(); 
    
[/code]

これでは共有メモリ上に `vector<float>` の本体を作っただけです。  
言い換えれば `vector<float> v;` としただけ、すなわち `vector` の管理用情報だけ作った状況です。  
ここで共有メモリにおきたいのは `vector` だけでなく `vector` が保持する内容のはず。  
`vector` の標準 allocator は内容を通常メモリに割り振るので目的と違う動作をします。  
必要なのは内容を共有メモリに割り振るような allocator を指定した `vector` です。

ってここまで書いたあたりで、既に適切な解答がついてるな・・・  
続きは @sayuri さんのコメントをどうぞ。


CC BY-SA 3.0
2015-08-19T22:05:22.407
14641
2015-08-19T22:05:22.407
8589
14637
answer