
Windows APIの質問です。
PINT GetShareInt() {
____HANDLE hmap = CreateFileMapping(
________INVALID_HANDLE_VALUE, NULL,
________PAGE_READWRITE,
________0, sizeof(int),
________TEXT("Share") );
____PINT pi = (PINT)MapViewOfFile(
________hmap, FILE_MAP_WRITE, 0, 0, 0);
____CloseHandle(hmap);
____return pi;
}
こんな感じの関数で変数をプロセス間共有したいのですが、
ファイルマッピングオブジェクトが毎回生成されてしまい、
変数を共有できません。
先にCloseHandleするのは後の処理がUnmapViewOfFileするだけで
すむからです。変則的ですが、MapViewOfFile呼び出ししている以上
hmapが指すカーネルオブジェクトは開放されないと思うのですが。
MapViewOfFileがカーネルオブジェクトの内部カウンタを進めていない、
ということでしょうか?それではマルチスレッドで扱えないような気が
するのですが、私の認識のどこが間違っているのでしょうか?
よろしくご指導お願い申し上げます。
No.5ベストアンサー
- 回答日時:
#1です。
>クラスオブジェクトのデストラクタとUnmapViewOfFileの機能は違いますよね。
>スマートポインタと言うんでしょうか?
正式な用語で言うところの「スマートポインタ」とは別物ですが、考え方は同じです。
もちろんオブジェクトのデストラクタとUnmapViewOfFileの機能は全然違うものです。しかしデストラクタでUnmapViewOfFileやCloseHandleを呼び出すようにしておけば、Closeし忘れていても自動的に開放されるというわけです。
>次のようにするとマッピングオブジェクトは共有さ>れるようです。
>PVOID GetMem() {
>----HANDLE hMap = CreateFileMapping(...
>----DWORD dwEroor = GetlastError();
>----PVOIE pMem = MapViewOfFle(...
>----if (dwError) CloseHandle(hMap);
>----return pMem;
>}
この場合は2度目の呼び出しのときはCloseHandleが実行されますが、1度目のときは実行されない(dwError==0となる)ので開放し忘れに気をつける必要があると思います。この方法で共有できるようですがやはりMicrososftが意図している通りの順序(Create、Map、Unmap、Close)で使用したほうがいいと思います。
>「共有の制約」とは何のことでしょうか?
>また、今回はページングファイルに支持されたメモリマップドファイルですから例外かもしれません。
確かに考えてみたらまったく関係がないかもしれません。すみません。共有の制約というのはhFileのshare属性のように思えますので。
http://www.microsoft.com/japan/msdn/library/ja/j …
ご返答ありがとうございます。
単純なデストラクタとCloseHandleのやっていることとは違う、ということを言いたかったんですが、釈迦に説法のようなことをしてしまい、赤面の至りです。
msdnの関数説明のところに書いてあったんですね。文書番号や「共有の制約」などで見当違いな検索をしていました。
>1度目のときは実行されない(dwError==0となる)ので開放し忘れに気をつける必要があると思います
理解しております。今回はシステムフックするDLLにコーディングしています。つまり最初に読み込むプロセスがフックの所有者であるため、このプロセスで解放する必要がないということで前述のコードにしたわけです。
>やはりMicrososftが意図している通りの順序(Create、Map、Unmap、Close)で使用したほうがいいと思います
これについてはもちろん同意します。現在のOSで動くからといってもドキュメントされていない以上、仕様はいつ変更されるかわかりませんよね。(Microsoftは極力、動作互換性を重視してくれるとは思いますが)
SDKを使う際にはメカニズムがどうなっているのかイメージしておきたいという気持ちがありますので、他人には理解されない質問かも、と思っていました。しかし数々のアドバイスをいただき、私なりに大変勉強になりました。
ご回答本当にありがとうございました。
No.4
- 回答日時:
ファイルマッピングとCloseHandleとはそういうものなのだと思います。
プロセスAでCreateFileMapping(..., TEXT("Share"));
プロセスAでCloseHandle
プロセスBでCreateFileMapping(..., TEXT("Share"));
プロセスBでCloseHandle
としたときに、プロセスBが新しいファイルマッピングオブジェクトを作るのは自然なことに思われます。
>MapViewOfFile呼び出ししている以上
>hmapが指すカーネルオブジェクトは開放されないと思うのですが。
「ユーザは全ハンドルを解放したが、マップトファイルが参照している」という状態で残るのかも…
解決策は、CloseHandleしない、というのが一番いいと思われます…
私も同じ結論を仮定していました。
「ユーザはマップトファイルの全ハンドルを解放したが、最低ひとつのビューが参照している状態」ではマップトファイルは解放されていないが取得することはできない。
そういうことだと思います。
kmb01さん、回答ありがとうございました。
No.3
- 回答日時:
#1です。
補足になります。MSDNではUnmapViewOfFileについて
----------------------
•Windows 95:1 つのファイルの最後のビューがまだアンマップされていない場合、そのファイルは引き続き開いていて、元のファイルハンドルと同じ共有の制約が適用されます。
•Windows NT/2000:1 つのファイルの最後のビューがまだアンマップされていない場合、そのファイルは引き続き開いていますが、共有の制約は適用されません。
----------------------
とありました。つまり、Win9x系ではyak3141さんの意図する通りに動作するのかもしれません。
この回答への補足
次のようにするとマッピングオブジェクトは共有されるようです。
PVOID GetMem() {
----HANDLE hMap = CreateFileMapping(...
----DWORD dwEroor = GetlastError();
----PVOIE pMem = MapViewOfFle(...
----if (dwError) CloseHandle(hMap);
----return pMem;
}
下の回答も含めてご返事が送れました。本当に丁寧な回答ありがとうございます。
「共有の制約」とは何のことでしょうか?
セキュリティフラグあるいはビューの読み書きモードのことですかね?
また、今回はページングファイルに支持されたメモリマップドファイルですから例外かもしれません。
msdnを早速探してみましたが目的の文書は見つけることはできませんでした。よろしければリンクを教えていただけないでしょうか?
回答のお礼が遅れた上でのあつかましいお願いですが、よろしければもう少しお付き合いくださいませ。
No.2
- 回答日時:
#1です。
>なぜ先にCloseHandleしてはいけないのでしょうか?
>こだわるのは
>1.解放忘れがない
>2.ひとつの変数だけ保持しておけばよいので楽
>というメリットがあるからなのですが、それだけで
詳しいメカニズムについて私は知りませんが。。。普通のメモリに例えるとおそらく以下のようになっているのではないでしょうか?
BYTE* pszBuff;
char* pCopy;
pszBuff = new BYTE[10]; //メモリ確保
pCopy = (char*)pszBuff; //アドレス取得
delete pszBuff; //メモリ開放忘れがないように先にdelete
strcpy(pCopy,"asss"); //取得したアドレスだから使えるはずだけど。。。
開放忘れを防ぎたいというのでしたら、以下のようなクラスを作成すればいいかと思います。
class CFileMapping
{
HANDLE _hMap;
HANDLE _hMem;
public:
CFileMapping(){_hMap = NULL;_hMem = NULL;}
~CFileMapping()
{
Unmap();
Close();
}
void Unmap()
{
if(_hMem) UnmapViewOfFile(_hMem);
_hMem = NULL;
}
void Close()
{
if(_hMap) CloseHandle(_hMap);
_hMap = NULL;
}
。。。。。そのたCreateFileMappingやMapViewなどをする関数を用意
};
再回答ありがとうございます。
クラスオブジェクトのデストラクタとUnmapViewOfFileの機能は違いますよね。スマートポインタと言うんでしょうか?
No.1
- 回答日時:
>先にCloseHandleするのは後の処理がUnmapViewOfFileするだけですむからです。
これが原因ではないでしょうか?
普通は
-----------------
hMap = CreateFileMapping()
pMem = MapViewOfFile()
処理
UnmapViewOfFile (pMem);
CloseHandle(hMap);
-----------------
のように使うかと思います。
早速の回答ありがとうございます。
質問でも述べさせていただきましたが、
なぜ先にCloseHandleしてはいけないのでしょうか?
こだわるのは
1.解放忘れがない
2.ひとつの変数だけ保持しておけばよいので楽
というメリットがあるからなのですが、それだけではなく
「MapViewOfFileした後なのに、CloseHandleするとマッピングオブジェクトが解放されてしまう」という現象をなぜそうなるのかメカニズムを知りたいと思い、質問させていただきました。
nitscapeさん、回答ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- Visual Basic(VBA) VBAが止まります。 2 2022/09/02 14:02
- その他(プログラミング・Web制作) Pythonのオブジェクトの関数について 2 2023/05/11 19:15
- その他(コンピューター・テクノロジー) 量子コンピュータの動作原理がわかりません。同じビットが、1でも0でも有って良いだろうか? 3 2023/02/04 03:20
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Visual Basic(VBA) エクセルのマクロについて教えてください。 4 2023/05/26 17:13
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
パワーポイントのVBAでテキスト...
-
CoCreateInstanceでエラーになる。
-
Vbで通常使用するプリンターを...
-
Strutsのbeanタグについて
-
ワイルドカード<?>と型パラメー...
-
ActiveDirectoryのユーザ情報の...
-
VBA 同じ名前のオブジェクトを...
-
サーブレットのクラス図について。
-
EXCEL VBAにて動的にCheckBOXを...
-
JAVAからHTMLへ値を返す方法
-
Visual Studioでのbmpファイル...
-
ヘッダファイルにおける文字列...
-
newは明示的にした方が良いのか?
-
Java認定試験3級の問題です。 ...
-
DOMの要素ををtextarea(dropし...
-
bmp画像をjpegやpng画像に圧縮...
-
iterator とiterableの関係がわ...
-
複数プロジェクト間での値渡し
-
ASP.NETから Java classファイル
-
VBScriptで計算して出た値をク...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
パワーポイントのVBAでテキスト...
-
Excelで =EMBED("Acrobat Docu...
-
VBA 同じ名前のオブジェクトを...
-
EXCEL VBAにて動的にCheckBOXを...
-
VBAのWindowオブジェクトとWork...
-
C#でフォームのオブジェクト名...
-
ビジュアルC++でボタンの有...
-
COMコンポーネントって何?
-
Object型からDouble型へのキャスト
-
時間帯判定をする。
-
newは明示的にした方が良いのか?
-
戻り値がクラスオブジェクト
-
ワイルドカード<?>と型パラメー...
-
error C2712: オブジェクト ア...
-
Accessの連結・非連結オブジェ...
-
CoCreateInstanceでエラーになる。
-
オブジェクトレベルとメタレベル
-
多人数のじゃんけんプログラム
-
Rangeオブジェクトを一時的に作...
-
ワードで画像をドロップすると...
おすすめ情報