メモリマップトファイル

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Cユーザー

メモリマップトファイル

#1

投稿記事 by Cユーザー » 12年前

現在共有メモリを作成するプログラムを組んでいます。

コード:

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のメンバーの倍数になっていないからというのが調べて分かりました。
     かといって倍数を指定するのは無理そうな感じがしました。

     ここからさきにすすめません。
     どのようなコードになるのでしょうか?
     ほかの方法で実現できれば他の方法でも構いません   
     以上ご教授お願い致します。  
     

}

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: メモリマップトファイル

#2

投稿記事 by h2so5 » 12年前

Cユーザー さんが書きました:      ここで問題があり、ヘッダーの後に9個のクラス情報を割り当てようとして、上記のようにマッピングしようとすると
     マッピング失敗になります。原因は引数にて指定しているdwFileOffsetLowがSYSTEM_INFOのメンバーの倍数になっていないからというのが調べて分かりました。
     かといって倍数を指定するのは無理そうな感じがしました。
倍数を指定するのが無理、とはどういうことでしょうか?

Cユーザー

Re: メモリマップトファイル

#3

投稿記事 by Cユーザー » 12年前

GetSysInfoなる関数で問題のメンバーの中身を見てみると65536でした。

開始サイズは512なので倍数にはならないと判断です。

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: メモリマップトファイル

#4

投稿記事 by h2so5 » 12年前

原因は引数にて指定しているdwFileOffsetLowがSYSTEM_INFOのメンバーの倍数になっていないからというのが調べて分かりました。
まずこの情報のソースはどこですか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリマップトファイル

#5

投稿記事 by softya(ソフト屋) » 12年前

この場合は一度に全部の塊の先頭アドレスを割り当てるべきだと思います。
小さな領域ごとにMapViewOfFile()でアドレスを割り振るものではありません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Cユーザー

Re: メモリマップトファイル

#6

投稿記事 by Cユーザー » 12年前

msdnにもかいてあります。
これだけじゃないかもですが。

http://msdn.microsoft.com/ja-jp/library/cc430198.aspx

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリマップトファイル

#7

投稿記事 by softya(ソフト屋) » 12年前

Cユーザー さんが書きました:msdnにもかいてあります。
これだけじゃないかもですが。

http://msdn.microsoft.com/ja-jp/library/cc430198.aspx
もしかして、dwAllocationGranularityの値の倍数じゃないと言いたいのでしょうか?
だとすれば言葉が不正確すぎます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Cユーザー

Re: メモリマップトファイル

#8

投稿記事 by Cユーザー » 12年前

>この場合は一度に全部の塊の先頭アドレスを割り当てるべきだと思います

それも検討してみました。けどやり方がよくわからないです。

typedef struct INFO
{
Header h;
ClassInfo* classinfo;
} CLASSINFO;


こういう全体の構造体をたすのはわかるんですが、これからどうればいいかが

Cユーザー

Re: メモリマップトファイル

#9

投稿記事 by Cユーザー » 12年前

言葉が不正確で申し訳ない。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリマップトファイル

#10

投稿記事 by softya(ソフト屋) » 12年前

共用メモリ空間にポインタを使ってはいけません。見えるプロセス毎にアドレスが違う可能性があるからです。
ポインタを使わない方法としては、この時の話題のメモリ確保の方法で良いのでは?
「メモリ確保(再) • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=12407#p99562
違うのはchar か構造体かって所だけです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Cユーザー

Re: メモリマップトファイル

#11

投稿記事 by Cユーザー » 12年前

まだイメージがわいてないのですが
共有メモリで全体のメモリ確保して、さらにmallocはしたくないんですよね

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリマップトファイル

#12

投稿記事 by softya(ソフト屋) » 12年前

mallocする必要はありません。
malloc()の代わりにCreateFileMapping()とMapViewOfFile()を行うだけです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Cユーザー

Re: メモリマップトファイル

#13

投稿記事 by Cユーザー » 12年前

本当に申し訳ないのですが
どうすればいいのかわかっておりません。

どんなサンプルでいいのでコードでお願いできませんか
お願いします

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリマップトファイル

#14

投稿記事 by softya(ソフト屋) » 12年前

まず、普通にmallocする形でコードを書いてみて下さい。
それをCreateFileMapping()とMapViewOfFile()に直すお手伝いをします。
malloc()が出来ないのなら、そこから勉強しなおしたほうが良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Cユーザー

Re: メモリマップトファイル

#15

投稿記事 by Cユーザー » 12年前

こんな感じでしょうか
以下の構造体を追加して
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));

Cユーザー

Re: メモリマップトファイル

#16

投稿記事 by Cユーザー » 12年前

うーん何か違うな・・
すいません、教えていただいてもよろしいでしょうか

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: メモリマップトファイル

#17

投稿記事 by みけCAT » 12年前

sizeof(CLASSINFO)ではなくて、sizeof(ClassInfo)ではないでしょうか。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリマップトファイル

#18

投稿記事 by softya(ソフト屋) » 12年前

なぜMapViewOfFile()がmalloc時に出てくるのでしょうか?
根本的にメモリ・仮想記憶の勉強をされた方が良いと思いました。
それなくして共有メモリをまともに扱えると思えないからです。

それと、MapViewOfFile()の出てくる順番も割り当てるサイズも間違っています。
あと割り当てられたメモリに値を書き込んだり、読みだしてちゃんと動作をするか確認するコードを書き加えるべきだと思います。
なんとなく大丈夫そうだってのが一番理解を妨げますよ。

HSP用に書かれた解説ですが、ここに書かれていることはちゃんと理解して下さい。
「プロセス間共有メモリ - Advanced HSP」
http://chokuto.ifdef.jp/advanced/sharedmem.html

512って決め打ちの数字も避けましょう。sizeof()じゃないと正しくない場合があります。
「データ型のアラインメントとは何か,なぜ必要なのか?」
http://www5d.biglobe.ne.jp/~noocyte/Pro ... nment.html

ともかく、急ぎすぎだと思います。
ちゃんと地固めしないとプロセス間通信は不安定極まりない物が出来上がります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Cユーザー

Re: メモリマップトファイル

#19

投稿記事 by Cユーザー » 12年前

仰る通りな気がしてきました。

ここは一旦閉めてメモリに関する質問に切り替えます

ありがとうございました

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: メモリマップトファイル

#20

投稿記事 by softya(ソフト屋) » 12年前

メモリマップドファイルの前に、バイナリファイルで別プログラムにデータを受け渡すプログラムを書いて見ることをオススメします。

【プログラムA】 データ作成
(1) mallocで領域を割り当て
(2) mallocの領域にデータを書き込む
(3) mallocの領域をバイナリファイルに出力

【プログラムB】 データ表示
(1) mallocで領域を割り当て
(2) mallocの領域にバイナリファイルから読み込む
(3) mallocの領域のデータを処理して表示。

まず、この2つプログラムが安定して動くものを作ってみましょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: メモリマップトファイル

#21

投稿記事 by ISLe » 12年前

メンバ個々のサイズで計算すると構造体の全体のサイズとはズレが生じる場合もあると思います。

そもそも構造体のサイズを512バイトにする意味があるのか疑問ですけど。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: メモリマップトファイル

#22

投稿記事 by ISLe » 12年前

質問者さんは解決したら見てないようなのでスレを無駄にしないために回答しておきたいと思います。

コード:

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に『置き換え』ます。

(追記)
コード間違ってたので修正しました。

Cユーザー

Re: メモリマップトファイル

#23

投稿記事 by Cユーザー » 12年前

うーん

ちゃんと見てるんですけどね
ただ共有メモリを使うレベルに達していないので
意見したり、質問したりはしないだけで

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: メモリマップトファイル

#24

投稿記事 by ISLe » 12年前

ポインタを理解してさえいれば共有メモリかどうかは関係ないです。
実際にmallocをMapViewOfFileに置き換えるだけで対応できるのですから。
#とわたしの投稿に書いてあります。

C言語を扱う上でポインタは基本中の基本ではないでしょうか。

Cユーザー

Re: メモリマップトファイル

#25

投稿記事 by Cユーザー » 12年前

ポインタも理解も微妙みたいなので
ちょっと難しいようです。

急ぎすぎました。
少しずつ勉強していきます

閉鎖

“C言語何でも質問掲示板” へ戻る