- ベストアンサー
バイナリ→構造体
- 仕様の都合でLong型のポインタにしたいと思ってます。
- VarPtrを使ってLong型のポインタに変換し、別の構造体に格納して共有メモリに移す方法を教えてください。
- 別ウインドウから共有メモリからデータを取り出し、Long型のポインタから構造体に戻す方法を教えてください。
- みんなの回答 (15)
- 専門家の回答
質問者が選んだベストアンサー
> ついでを言えば、共有メモリを扱うクラスもあります。こんな感じです。 ということでどんな実装になっているかがわかったので、 対応策を。 対応策1 Cue構造の要素1つずつに個別の領域をSetBuffName()を使って割り当てて行き、要素の位置はアドレスではなく領域名を導き出せる数字等(たとえば"Cue1"だったら1)を別の構造体に格納して連結していく 対応策2 要素1つずつに個別の共有メモリを割り当てるのではなく一括にしか取得できない場合は、VarPtr()で取得されるローカルの変数のアドレスを入れるのではなく、共有メモリに書き込む大きな領域の先頭からのオフセットを入れておく。 みたいな感じでできそうですね。 やっぱり対応策1が楽かな。
その他の回答 (14)
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>そういう事ですか…しかし、何もVBごと落ちなくてもいいじゃないかと思うんですがそこの所どうなんでしょう某MS社の偉い人。 WinAPIの使い方間違ってればしょうがないです。VBそのもののプロセスのメモリを破壊してるんですから。 >…と思って二回CopyMemoryを(管理用構造体、内部データの二回)して見たんですが…やはりVBごと落ちてしまいます。 2回するのはいいんですが、 >1、VarPtrを使ってLong型のポインタに変換(してると思ってます) これそのままにしてません? VarPtrで取得できるのはあくまでも呼び元のプロセスで確保している領域のアドレスです。 >2、それを別の構造体に格納、その構造体を共有メモリに移す。 つまり、ここで本来格納しないといけないアドレスは、 1回目のCopyMemoryのコピー先アドレスですよね。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>CopyMemoryは試したんですが、VBごと落ちてしまいます。 > …構造体のサイズが大きすぎて使えない…とか? プロセスが違うから、Longに格納したアドレスが無効なんで落ちるんじゃなくて? > 64Byteの構造体(ユーザー定義型)です。 > 中身はstring型とLong型が計16個です。 この構造体の領域自体、共有メモリ上にないとだめなのは理解されてますか? もしくは共有メモリ上にこの構造体の内容をそのままCopyMemoryしてますか?(そしたら、別の構造体に入れるアドレスは共有メモリ上をさしますよね)
補足
>>CopyMemoryは試したんですが、VBごと落ちてしまいます。 >> …構造体のサイズが大きすぎて使えない…とか? >プロセスが違うから、Longに格納したアドレスが無効なんで落ちるんじゃなくて? そういう事ですか…しかし、何もVBごと落ちなくてもいいじゃないかと思うんですがそこの所どうなんでしょう某MS社の偉い人。 >> 64Byteの構造体(ユーザー定義型)です。 >> 中身はstring型とLong型が計16個です。 >この構造体の領域自体、共有メモリ上にないとだめなのは理解されてますか? >もしくは共有メモリ上にこの構造体の内容をそのままCopyMemoryしてますか?(そしたら、別の構造体に入れるアドレスは共有メモリ上をさしますよね) 理解していませんでした(ぉぃ)サイズ以前の問題ですか…こちらもCopyMemoryして共有メモリ上に上げておく必要がある…つまり、二回CopyMemoryをする必要があるんですね。 …と思って二回CopyMemoryを(管理用構造体、内部データの二回)して見たんですが…やはりVBごと落ちてしまいます。 一応、classを使って共有メモリに構造体を渡す事はできているんですが、OCXと言う壁があるとどうにもうまく行かない物なんでしょうか…出来る気がしてなら無いんですが。
- 2ch
- ベストアンサー率51% (64/125)
一応共有メモリに関して、サンプルを書いた事があるので http://oshiete1.goo.ne.jp/kotaeru.php3?q=817941 それと >CopyMemoryは試したんですが、VBごと落ちてしまいます。 CopyMemoryの宣言や、その引数がわからないことには、誰もこのことには発言不可能 APIビューア通りの Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) としているなら、ポインタの値渡しが鉄則 call copymemory(ByVal [先頭アドレス],ByVal [先頭アドレス],[長さ]) 『ByVal』 付けてます?
お礼
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _ (cStr1 As Any, cStr2 As Any, ByVal iLen As Long) CopyMemoryの宣言はこれです…同じ物ですよね? ByVal はきちんと使って渡しているんですが… とりあえず、参考URL熟読して次の案を出してみます。ありがとうございました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
>1、VarPtrを使ってLong型のポインタに変換(してると思ってます) できるはずですが、何の変数のアドレスをVarPtr使ってLongの数値にしてるんですか?質問文から読み取れないんですが。 >2、それを別の構造体に格納、その構造体を共有メモリに移す。 > >3、別ウインドウから取り出し、最初のLongのポインタを引き抜く これって別プロセスですか? プロセス違う時点でポインタは無効になりますけど。 >4、Long型ポインタから構造体に戻す CopyMemoryでしょ、ここで。 ということで、根本的なところがまずいような。 >1と4はOCXを扱う側、2と3はOCX内で行ってます。 1を扱う側でやっちゃまずいでしょ。共有メモリ内のアドレスでなければいけないんですから、扱う側で使い始める前にアドレスはわかってないといけないはずですよね。 >共有メモリを扱うOCXを作る必要がありまして、 なぜOCX?ActiveX EXEという選択肢はNGだったんですか? これならプロセス空間を意識しないで情報のやり取りできますが。
補足
>> 1、VarPtrを使ってLong型のポインタに変換(してると思ってます) > できるはずですが、何の変数のアドレスをVarPtr使ってLongの数値にし > てるんですか?質問文から読み取れないんですが。 64Byteの構造体(ユーザー定義型)です。 中身はstring型とLong型が計16個です。 >> 2、それを別の構造体に格納、その構造体を共有メモリに移す。 >> 3、別ウインドウから取り出し、最初のLongのポインタを引き抜く > これって別プロセスですか? > プロセス違う時点でポインタは無効になりますけど。 3で別なウインドウになるので別プロセスになると思いますが…う、駄 目ですか。 >> 4、Long型ポインタから構造体に戻す > CopyMemoryでしょ、ここで。 CopyMemoryは試したんですが、VBごと落ちてしまいます。 …構造体のサイズが大きすぎて使えない…とか? >> 共有メモリを扱うOCXを作る必要がありまして、 > なぜOCX?ActiveX EXEという選択肢はNGだったんですか? > これならプロセス空間を意識しないで情報のやり取りできますが。 そこは上司にOCXで作れといわれまして… ActiveX EXEと言う物があるんですか。調べてみましたが確かにこちらの方が適任かも…
- 1
- 2
お礼
つまり…BufNameをバッファ名として渡された場合、BufName_1、BufName_2、みたいな感じでOCX内で定義してバッファを並べればいい訳ですね?で、それを管理する構造体を作り、読み込む構造体の名前を格納しておく…ってなんだか分かったような分かって無いような言い方してますが、出来てるので分かったんだと思います。まあ、アドレスにこだわったのがそもそもの間違いだと… お二人には大変ご迷惑をおかけいたしました。おかげさまで足りない頭でも何とか完成には至れました…分かってみれば単純な理屈でしたけど。何故これが思いつかなかったのかと… 初めからこの実装を出していれば話もこじれずに済んだのかもしれませんが…色々と勉強させていただいただきました。Lenやポインタの事もどこかでそのうち参考にさせていただきます。 本当にありがとうございました。