2012年7月4日水曜日

boostの共有メモリで画像を受け渡しする

boostの共有メモリを使ってプログラムAからBに画像を受け渡すサンプルコード.結果は正しく画像を受け渡すことが出来たが,共有メモリ上に確保したvectorをresizeしていいのかな・・・参考ページではpush_backなどしているのでいいじゃないかと.

使用したライブラリ・環境
  • boost1.46.1
  • OpenCV2.40 (画像の読み書き)
  • windows.h  (Sleepのため)
  • Windows7 64bit Pro
  • Visual Studio 9 Sp1

共通部分

#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/sync/scoped_lock.hpp>
#include <windows.h>
#include <opencv2/opencv.hpp>
using namespace boost::interprocess;
 
typedef allocator<unsigned char, managed_shared_memory::segment_manager> shmalloc;
typedef vector<unsigned char, shmalloc> shmimage; //boost::interprocess::vector

プログラムA(transmitter)

int main( int argc, char* argv[] )
{
    // 共有メモリ領域を作る.画像サイズ+α(どれだけ必要なのか良くわかりません・・・)
    shared_memory_object::remove( NAME );
    managed_shared_memory shm(open_or_create, NAME, 640*480*3+1024);
 
    //アロケータを作成
    const shmalloc alloc_inst (shm.get_segment_manager());
 
    // 共有メモリ内にvectorを作る
    shmimage *image = shm.construct< shmimage >("Image")(alloc_inst);
    shmimage& imref = *image;
    imref.resize(640*480*3); //こんなコトしていいのか?他にやり方が分からん
 
    //画像を読み込み共有メモリに書き込む
    cv::Mat_<cv::Vec3b> im = cv::imread("test.jpg");
    memcpy(&imref[0], im.data, 640*480*3);
 
    Sleep(1000*10);
}

プログラムB(receiver)

 int main( int argc, char* argv[] )
{
    // 共有メモリ領域を開く(なければ作る。1024バイト)
    managed_shared_memory shm(open_only, NAME);
 
    // 共有メモリ内のvectorを取得
    shmimage *image = shm.find< shmimage >("Image").first;
 
    //画像をコピーして保存 
    cv::Mat_<cv::Vec3b> im(480, 640);
    shmimage& imref = *image;
    memcpy(im.data, &imref[0], 640*480*3);
    cv::imwrite("received.jpg", im);
 
    Sleep(1000*10);
} 

問題点

  • 起動順序がA、Bの順でなければならないこと
  • 共有メモリの領域サイズを画像サイズ+1024Bとアドホックな決め方をしていること。