ページ 11

64bitOSにおけるグローバルメモリの扱いについて

Posted: 2011年3月01日(火) 18:46
by ねこ
お世話になっております、ねこです。

現在の業務にて以下のような構成で開発をしております。
開発環境:WindowsXP 32bit
コンパイラ:VisualStudio 2008(C++/C#)

プログラムA(C#)
プログラムB(C++(MFC))
どちらもダイアログベースの実行ファイルです。

Bは直接起動はせず、Aから起動されます。
その時コマンド引数にAのウィンドウハンドルを渡し、
Bはそれを受け取り自身のウィンドウハンドルをAに対しSendMessage( Aハンドル, ... )で送信します。
これにより相互にウィンドウハンドルを保持した状態になります。

A,B共に起動後は何もせず、何かしらSendMessageでメッセージが来たら対応する処理を実行します。
大量のデータを扱う場合もあり、その際は送信元でグローバルメモリにデータを保持し処理IDとメモリアドレスを送信し、
受信先でメモリアドレスのデータを参照するという形になっています。

しかし、実際にこれらが実行される環境が64bitOSという話になり
ウィンドウハンドルやグローバルメモリのアドレスがこのままでいいのか不安になっています。

64bit環境自体が無く、動作確認も出来ないためどのように対応したらいいのか分からない状態です。
32bit環境でコンパイルしたアプリケーションでもメモリアドレスに関係するものなどは64ビットアドレス用に8バイト確保するよう修正する必要があるのでしょうか?
漠然とした質問になりましたが、回答をお願いします。

Re: 64bitOSにおけるグローバルメモリの扱いについて

Posted: 2011年3月01日(火) 23:28
by softya(ソフト屋)
グローバルメモリをGMEM_FIXEDしたのを受け渡すんですよね。
どうなるか分かんないですね。

とりあえず、WOW64がどこまでやってくれるか試してみるしか無いと思います。
ついでに、メモリマップドファイルを試してみたほうが良いかも。

テストコードを提供してもらえば、試してみますが?
当方Win7Pro 64bitです。

Re: 64bitOSにおけるグローバルメモリの扱いについて

Posted: 2011年3月02日(水) 01:29
by ISLe
32ビットウインドウズでもプロセスを跨いで渡したポインタで相手プロセスのメモリに直接アクセスすることはできないはずですけど、動作検証はできているのでしょうか?

Re: 64bitOSにおけるグローバルメモリの扱いについて

Posted: 2011年3月02日(水) 08:10
by ねこ
>softya(ソフト屋)様 ISLe様
返信ありがとうございます。

<グローバルメモリをGMEM_FIXEDしたのを受け渡すんですよね。
<どうなるか分かんないですね。
現状ではC#でSystem.Marshal.StringToHGlobalAnsiで文字列をグローバルメモリに格納した後そのポインタを渡し、
C++でその文字バッファを取得しています。

<とりあえず、WOW64がどこまでやってくれるか試してみるしか無いと思います。
<ついでに、メモリマップドファイルを試してみたほうが良いかも。
やはり実際の環境が無いと難しいですか・・・
メモリマップドファイルも試してみました。こちらの方が大丈夫のような感じがするので検討してみたいと思います。

<テストコードを提供してもらえば、試してみますが?
社内資産なので提供は難しいです。時間が取れたら同様のコードを自宅にて作成してみます。

<32ビットウインドウズでもプロセスを跨いで渡したポインタで相手プロセスのメモリに直接アクセスすることはできないはずですけど、動作検証はできているのでしょうか?
アプリの持つ仮想メモリアドレスを相手に渡した場合、という認識で良いのでしょうか?
グローバルメモリに必要なサイズを確保してメモリ複製する流れを想定しているのですが、
確保するデータの種別に関しては動作検証不足です。
おおよそ文字列だけなので文字コードに気を付けていれば良いのかな・・・くらいしか現状では考えられていません。

以上、返信となります。

Re: 64bitOSにおけるグローバルメモリの扱いについて

Posted: 2011年3月02日(水) 16:53
by ISLe
ねこ さんが書きました:アプリの持つ仮想メモリアドレスを相手に渡した場合、という認識で良いのでしょうか?
グローバルメモリに必要なサイズを確保してメモリ複製する流れを想定しているのですが、
確保するデータの種別に関しては動作検証不足です。
おおよそ文字列だけなので文字コードに気を付けていれば良いのかな・・・くらいしか現状では考えられていません。
その方法では32ビットウインドウズでも相手プロセスでデータを受け取ることはできないはずですが。
開発環境で実行して確かめたことはないのですか?
アプリケーションから見えるメモリアドレスはプロセス固有の仮想アドレスなので、アドレス値を受け取って同じアドレスを見ても自プロセスのメモリ内容が見えるだけです。

メモリ内容を外部プロセスに渡す方法はいくつかあります。
  1. VirtualAllocExで共有メモリを確保して読み書きする
  2. SendMessageでWM_COPYDATAを投げる
  3. プロセス間通信(mailslotやpipe)
  4. さらに原始的な方法(ファイルでやり取りとか)
いずれも素直にコーディングすれば32ビット64ビットを意識しなくて済むはずです。