QSharedMemoryを使ったメモリの共有
Qtでアプリを作る場合、ポインタを多用しなくていいのでオブジェクトをメモリ確保するということは少なくなると思います。
しかし、異なるクラス間やプロセス間で画像データなどの大きなデータのメモリを共有したい場合はメモリーを共有したほうがいい場合もあります。
そういうときはQSharedMemoryという便利なクラスがあるので、それを使うと楽です。
このクラスはメモリーにキー名を結びつけて管理できるのでどこからでも確保したメモリにアクセスできるようになります。
メモリに書き込み
初めにQSharedMemoryを使ってメモリーに何か値を書き込んでみます。
#include <QSharedMemory> class MemoryWriter { MemoryWriter() { QSharedMemory sharedMemory("dataKey"); const char * src = "shared data"; int size = strlen(src); if(!sharedMemory.create(size)){ qCritical() << "Unable to create shared memory"; } sharedMemory.lock(); ///メモリーを使用する char * memory = (char *)(sharedMemory.data()); memcpy(memory, src, size); ///メモリに書き込み sharedMemory.unlock(); ///メモリーの所有権を放棄 } }
こんなクラスを作ってみました。
このクラスでは"dataKey"というキー名でchar型のメモリを共有しました。
メモリを読み込んだり書き込んだりする前にはlockを呼び、終わった後にはメモリの所有権を他に渡すためにunlockする必要があります。
メモリの読み込み
今度は書き込んだメモリを読みだしてみます。
例えば次のようにします。
#include "MemoryWriter.h" int main(int argc, char * argv[]) { QApplication a(argc, argv); MemoryWriter writer; QSharedMemory sharedMemory("dataKey"); sharedMemory.attach(); ///使用済みのメモリにアクセス sharedMemory.lock(); qDebug() << "Shared data = " << QString((char*)sharedMemory.constData()); sharedMemory.unlock(); return a.exec(); }
読み出しの場合はconstDataから値へのポインタを取得できます。
ただし、すでに割り振られているメモリにアクセスするときはattach関数を呼び出す必要があります。
また、書き込みの時と同じようにlockとunlockを忘れず書きましょう。
メモリの解放
使わなくなったメモリは解放しなければならないので、そのときはdetach関数を実行します。
QSharedMemory sharedMemory("dataKey"); sharedMemory.detach(); ///メモリ解放
これだけです。
まとめ
いままでのことをまとめると次のようになります。
- キー名でメモリにアクセスできる。
- メモリへのデータを読み込み・書き込みする前にlockを実行
- メモリへのデータの読み込み・書き込みが終わったらunlockを実行
- メモリの解放にはdetachを使う。
大まかに書くとこのような手順です。
メモリの共有というとなんだか難しそうですが、QSharedMemoryを使えばキーだけでメモリに読み込んだり書き込んだりできるので扱いやすいです。
以上、メモリの共有でした。では、また!
© Kaz