掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
GlobalAllocにCopyMemoryで構造体をコピーするには (ID:101920)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
そのコードだと、メモリ破壊を引き起こしてしまうかと。 > lBytes = Len(oMM) これは 8 バイトになっていますよね。 > oMM.lNum1 = 1 > oMM.lNum2 = 2 そしてこの時点で、oMM が指すメモリは 01 00 00 00 02 00 00 00 という 8 バイトのデータになります。 > Call CopyMemory(lpDest:=hGLock, lpSrc:=oMM, lSize:=lBytes) ここに問題があります。 hGLock という値は Long 型です。4 バイト分の領域しかないにも関わらず、 そこに 8 バイトのデータを書き込もうとしている事になります。 残りの 4 バイトは、変数 hGLock 以外の領域に対して書き込まれる事になります。 今回は、それがたまたま hGAlloc に書き込まれてしまった、という事でしょう。 > このプログラムでCopyMemoryを実行すると、変数hGLockの値が変わってしまうのです。 > 具体的にはhGLockにはアドレスの値が入ってるハズなのですが、"2"になってしまい、 > hGAllocの値が"1"になってしまうのです。 それは、hGLock と hGAlloc の変数領域が、隣あうメモリ空間に配置されていたためです。 変数宣言が Dim hGAlloc As Long, hGLock As Long ではなく Dim dummy1 As Long Dim hGAlloc As Long Dim dummy2 As Long Dim hGLock As Long Dim dummy3 As Long になっていれば、hGLock = 1、dummy2 = 2 となるかも知れません。 何にしても、他の変数領域にデータを書き込んでしまっている以上、 CopyMemory API の使い方が間違っている、という事になりますね。 > 第1引数に渡されるLong型がそのままアドレスとして認識されるのであれば、その > アドレスが指し示す領域に指定したサイズのデータがコピーされると思います。 今のコードは、「hGLock が指し示すアドレス」に対して書き込むのではなく、 「hGLock そのもの」に対して書き込むコードになっています。 アドレスに対して書き込みたいのであれば、API の呼び出し部分を Call CopyMemory(lpDest:=ByVal hGLock, lpSrc:=oMM, lSize:=lBytes) のように『ByVal』指定にするか、もしくは CopyMemory API の宣言部で、 第一引数を「ByVal Long」か「ByVal Any」にしておく必要があります。 (API 宣言が異なれば、API の呼び出し方も変わる事に注意してください) > でも、他のサイトと見てもこのような方法で確保したメモリにコピーできるようなのです。 ByVal/ByRef の扱いに誤りが無いか、もう一度確認してみてください。
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.