- 題名: Marshal.AllocCoTaskMemの16バイト境界
- 日時: 2012/08/01 19:29:26
- ID: 30792
- この記事の返信元:
- (なし)
- この記事への返信:
- [30793] Re[1]: Marshal.AllocCoTaskMemの16バイト境界2012/08/01 21:48:18
- ツリーを表示
■No30817に返信(Aruさんの記事) 提示されたコードで気になるとこがあるのですが > Public Shared Sub ByteAligen(ByVal size As Integer, ByRef retPtr As ここのsizeにわたされる値はAlign = 16 の倍数になっているのでしょうか? なっていない場合があるとするとわたされたsizeを16の倍数に切上げてAlign-1を足さないとはみ出てしまうきがします。 例)Align=4, Size=5 □または■が確保領域、■または×がDLLで書かれるであろう領域 012301230123 確保領域のOffset=0 ■■■■■■■■ '--- Size + Align - 1の場合 ■■■■■■■■ '--- (Sizeを4の倍数に切上げ) + Align - 1の場合 確保領域のOffset=1 □□□■■■■■××× '--- Size + Align - 1の場合 □□□■■■■■■■■ '--- (Sizeを4の倍数に切上げ) + Align - 1の場合 確保領域のOffset=2 □□■■■■■■×× '--- Size + Align - 1の場合 □□■■■■■■■■□ '--- (Sizeを4の倍数に切上げ) + Align - 1の場合 確保領域のOffset=3 □■■■■■■■× '--- Size + Align - 1の場合 □■■■■■■■■□□ '--- (Sizeを4の倍数に切上げ) + Align - 1の場合
分類:[.NET]
初投稿ですが、他トピックにはいつもお世話になっています。
今回VB.Net2008にてCで作られたDLLを呼び出して使用するのですが、メモリの確保が必要となりました。
DLLの動作としては、アドレスとサイズ(と場所)を指定して呼び出したのちに、そのアドレスをMarshal.Copyでバッファにコピーすることで様々な情報を扱おうとするものです(Byteデータ)
DLL自体は動作し、問題なく使用できているのですが、特定の確保したアドレスを使用する箇所でMarshal.Copyを行うと高頻度で「保護されているメモリに読み取りまたは書き込み操作を行おうとしました。・・・」のエラーが発生します。
Copy自体は
Marshal.Copy(ptr, buf, 0, size)
のように書いてあり、他にも多数使用しています
(他のアドレスの箇所では発生しません)
しかもこの関数呼び出し直後は発生せず、bufの内容もちゃんとCopyされていますが、なぜかAltキー押下やプログラム終了時などに上記エラーが発生します。
そこでMarshal.AllocCoTaskMemかと思い見直していましたが、現状おかしな箇所が私には分からず投稿しました。
確保しているサイズ、コピー先のバッファサイズも同じ値でした
DLLの仕様上16バイトの区切りでなければならなく、以下のようにソースを書きました。
Public Shared Sub ByteAligen(ByVal size As Integer, ByRef retPtr As IntPtr)
Dim ptr As IntPtr
Dim pBufferAlign As UInt32
ptr = Marshal.AllocCoTaskMem(size + &H8) ' allocate memory(require 8 byte align)
If (CUInt(ptr) And &H8) Then
pBufferAlign = CUInt(ptr) + 8
Else
pBufferAlign = CUInt(ptr)
End If
retPtr = CType(pBufferAlign, IntPtr)
End Sub
該当のMashal.Copyをコメントにすれば発生しないため、エラー内容からしても確保したメモリ絡みだとは思うのですが、なにぶん解決には至っておりません。
分かる方がいらっしゃいましたらよろしくお願いいたします。