ページ 1 / 1
メモリマップトファイル
Posted: 2013年2月06日(水) 00:46
by Cユーザー
現在共有メモリを作成するプログラムを組んでいます。
コード:
typedef struct Header
{
unsigned long point;
unsigned long size;
char dummy[512 - sizeof(unsigned long) - sizeof(unsigned long)];
} HEADER;
typedef struct ClassInfo
{
unsigned long number;
char biko[512 - sizeofunsigned long )];
} CLASSINFO;
共有メモリのフォーマット的には
【ヘッダー(512バイト固定) 】 + 【クラス情報(512バイト) × <ユーザー指定> 】となっています。
(例) ユーザーが9クラスの情報が欲しい!といえば ヘッダー(512) + クラス情報(512×9) = 5120の共有メモリを作成する。
この共有メモリを作成するプログラムとして私が考えたのが以下になります。
------------------------------------------------------------------------------------------------------------------------------
int m_Count = 9;//ユーザーが指定するクラス数
void Test()
{
// まず共有メモリを作成する。メモリをかんがえる
long Size = 512 + m_Count * 512;//今回の場合5120バイト
HANDLE handle= CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
Size, //共有メモリサイズ
"ClassProgram")
);
//この後各領域を割り当てる。まずヘッダー 512バイト
HEADER *header= (HEADER*)MapViewOfFile(handle,
FILE_MAP_ALL_ACCESS, // 読書き両方
0,
0,
sizeof(HEADER ));
//次に9個のクラス情報を割り当てる 512x9バイト
CLASSINFO *classInfo = (CLASSINFO *)MapViewOfFile(handle,
FILE_MAP_ALL_ACCESS, // 読書き両方
0,
sizeof(HEADER),
sizeof(CLASSINFO) * 9 );
ここで問題があり、ヘッダーの後に9個のクラス情報を割り当てようとして、上記のようにマッピングしようとすると
マッピング失敗になります。原因は引数にて指定しているdwFileOffsetLowがSYSTEM_INFOのメンバーの倍数になっていないからというのが調べて分かりました。
かといって倍数を指定するのは無理そうな感じがしました。
ここからさきにすすめません。
どのようなコードになるのでしょうか?
ほかの方法で実現できれば他の方法でも構いません
以上ご教授お願い致します。
}
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 00:52
by h2so5
Cユーザー さんが書きました:
ここで問題があり、ヘッダーの後に9個のクラス情報を割り当てようとして、上記のようにマッピングしようとすると
マッピング失敗になります。原因は引数にて指定しているdwFileOffsetLowがSYSTEM_INFOのメンバーの倍数になっていないからというのが調べて分かりました。
かといって倍数を指定するのは無理そうな感じがしました。
倍数を指定するのが無理、とはどういうことでしょうか?
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:00
by Cユーザー
GetSysInfoなる関数で問題のメンバーの中身を見てみると65536でした。
開始サイズは512なので倍数にはならないと判断です。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:15
by h2so5
原因は引数にて指定しているdwFileOffsetLowがSYSTEM_INFOのメンバーの倍数になっていないからというのが調べて分かりました。
まずこの情報のソースはどこですか?
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:19
by softya(ソフト屋)
この場合は一度に全部の塊の先頭アドレスを割り当てるべきだと思います。
小さな領域ごとにMapViewOfFile()でアドレスを割り振るものではありません。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:21
by Cユーザー
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:23
by softya(ソフト屋)
もしかして、dwAllocationGranularityの値の倍数じゃないと言いたいのでしょうか?
だとすれば言葉が不正確すぎます。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:28
by Cユーザー
>この場合は一度に全部の塊の先頭アドレスを割り当てるべきだと思います
それも検討してみました。けどやり方がよくわからないです。
typedef struct INFO
{
Header h;
ClassInfo* classinfo;
} CLASSINFO;
こういう全体の構造体をたすのはわかるんですが、これからどうればいいかが
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:31
by Cユーザー
言葉が不正確で申し訳ない。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:33
by softya(ソフト屋)
共用メモリ空間にポインタを使ってはいけません。見えるプロセス毎にアドレスが違う可能性があるからです。
ポインタを使わない方法としては、この時の話題のメモリ確保の方法で良いのでは?
「メモリ確保(再) • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=12407#p99562
違うのはchar か構造体かって所だけです。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:49
by Cユーザー
まだイメージがわいてないのですが
共有メモリで全体のメモリ確保して、さらにmallocはしたくないんですよね
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:53
by softya(ソフト屋)
mallocする必要はありません。
malloc()の代わりにCreateFileMapping()とMapViewOfFile()を行うだけです。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:57
by Cユーザー
本当に申し訳ないのですが
どうすればいいのかわかっておりません。
どんなサンプルでいいのでコードでお願いできませんか
お願いします
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 01:59
by softya(ソフト屋)
まず、普通にmallocする形でコードを書いてみて下さい。
それをCreateFileMapping()とMapViewOfFile()に直すお手伝いをします。
malloc()が出来ないのなら、そこから勉強しなおしたほうが良いと思います。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 02:19
by Cユーザー
こんな感じでしょうか
以下の構造体を追加して
typedef struct INFO
{
Header h;
ClassInfo classinfo[1];
} INFO;
//マッピングするときはこんな感じでしょうか
//INFO構造体でマッピング
INFO *info = (INFO*)MapViewOfFile(handle,FILE_MAP_ALL_ACCESS, 0,0, sizeof(INFO) );
//メモリ確保
struct INFO *info2 = (struct INFO *)malloc(sizeof(struct INFO)+512*9 -sizeof(CLASSINFO));
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 02:21
by Cユーザー
うーん何か違うな・・
すいません、教えていただいてもよろしいでしょうか
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 07:19
by みけCAT
sizeof(CLASSINFO)ではなくて、sizeof(ClassInfo)ではないでしょうか。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 11:40
by softya(ソフト屋)
なぜMapViewOfFile()がmalloc時に出てくるのでしょうか?
根本的にメモリ・仮想記憶の勉強をされた方が良いと思いました。
それなくして共有メモリをまともに扱えると思えないからです。
それと、MapViewOfFile()の出てくる順番も割り当てるサイズも間違っています。
あと割り当てられたメモリに値を書き込んだり、読みだしてちゃんと動作をするか確認するコードを書き加えるべきだと思います。
なんとなく大丈夫そうだってのが一番理解を妨げますよ。
HSP用に書かれた解説ですが、ここに書かれていることはちゃんと理解して下さい。
「プロセス間共有メモリ - Advanced HSP」
http://chokuto.ifdef.jp/advanced/sharedmem.html
512って決め打ちの数字も避けましょう。sizeof()じゃないと正しくない場合があります。
「データ型のアラインメントとは何か,なぜ必要なのか?」
http://www5d.biglobe.ne.jp/~noocyte/Pro ... nment.html
ともかく、急ぎすぎだと思います。
ちゃんと地固めしないとプロセス間通信は不安定極まりない物が出来上がります。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 13:09
by Cユーザー
仰る通りな気がしてきました。
ここは一旦閉めてメモリに関する質問に切り替えます
ありがとうございました
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 13:17
by softya(ソフト屋)
メモリマップドファイルの前に、バイナリファイルで別プログラムにデータを受け渡すプログラムを書いて見ることをオススメします。
【プログラムA】 データ作成
(1) mallocで領域を割り当て
(2) mallocの領域にデータを書き込む
(3) mallocの領域をバイナリファイルに出力
【プログラムB】 データ表示
(1) mallocで領域を割り当て
(2) mallocの領域にバイナリファイルから読み込む
(3) mallocの領域のデータを処理して表示。
まず、この2つプログラムが安定して動くものを作ってみましょう。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 17:08
by ISLe
メンバ個々のサイズで計算すると構造体の全体のサイズとはズレが生じる場合もあると思います。
そもそも構造体のサイズを512バイトにする意味があるのか疑問ですけど。
Re: メモリマップトファイル
Posted: 2013年2月06日(水) 18:26
by ISLe
質問者さんは解決したら見てないようなのでスレを無駄にしないために回答しておきたいと思います。
コード:
typedef struct {
unsigned long point;
unsigned long size;
} HEADER;
typedef struct {
unsigned long number;
} CLASSINFO;
typedef struct {
HEADER header;
CLASSINFO classinfo[1];
} INFO;
int m_Count = 9; // ユーザーが指定するクラス数
size_t size = sizeof(INFO) + sizeof(CLASSINFO) * (m_Count - 1);
INFO *info = (INFO *)malloc(size);
HEADER *header = &info->header;
CLASSINFO *classinfo = info->classinfo;
共有メモリを使う場合は、mallocをMapViewOfFileに『置き換え』ます。
(追記)
コード間違ってたので修正しました。
Re: メモリマップトファイル
Posted: 2013年2月08日(金) 00:16
by Cユーザー
うーん
ちゃんと見てるんですけどね
ただ共有メモリを使うレベルに達していないので
意見したり、質問したりはしないだけで
Re: メモリマップトファイル
Posted: 2013年2月08日(金) 00:30
by ISLe
ポインタを理解してさえいれば共有メモリかどうかは関係ないです。
実際にmallocをMapViewOfFileに置き換えるだけで対応できるのですから。
#とわたしの投稿に書いてあります。
C言語を扱う上でポインタは基本中の基本ではないでしょうか。
Re: メモリマップトファイル
Posted: 2013年2月08日(金) 00:37
by Cユーザー
ポインタも理解も微妙みたいなので
ちょっと難しいようです。
急ぎすぎました。
少しずつ勉強していきます