Marshal.PtrToStructure メソッド (IntPtr, Type) VBコーディングで悩んだこと [開発環境]
C#版のサンプルコードを参考にVBでコーディングしても、期待した結果が得られなかった原因がMarshal.PtrToStructure の使用方法にあったので記録しておく。
CTypeを使用し、指定の構造体型に式を変換する必要があった。
' マネージ構造体を作成し、アンマネージ メモリに転送した後、PtrToStructure メソッドを使用してマネージ メモリに再度転送するコード例。
Imports System
Imports System.Runtime.InteropServices' 構造体
Public Structure Point
Public x As Integer
Public y As Integer
End Structure
Module Module1Sub Main()
' 構造体の宣言
Dim p As Point
p.x = 1
p.y = 1Console.WriteLine("The value of first point is " + p.x.ToString + " and " + p.y.ToString + ".")
' 構造体用のアンマネージメモリを確保
Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(p))Try
' 構造体をアンマネージメモリにコピー
Marshal.StructureToPtr(p, pnt, False)' 別の構造体宣言
Dim anotherP As Point' アンマネージデータをマネージ構造体にマーシャリング(データ変換)
anotherP = CType(Marshal.PtrToStructure(pnt, GetType(Point)), Point)
' C#の場合、以下の記述となるので要注意
' anotherP = (Point)Marshal.PtrToStructure(pnt, typeof(Point));
' または
' Marshal.PtrToStructure(pnt, anotherP.GetType());
' となるので注意Console.WriteLine("The value of new point is " + anotherP.x.ToString + " and " + anotherP.y.ToString + ".")
Finally
' アンマネージメモリの解放
Marshal.FreeHGlobal(pnt)
End TryConsole.ReadKey()
End SubEnd Module
参考サイト
- http://www.mnc.co.jp/INtime/user/intimedev.php?.NET%A5%A2%A5%D7%A5%EA%A5%B1%A1%BC%A5%B7%A5%E7%A5%F3%A4%CB%A4%AA%A4%B1%A4%EB%B6%A6%CD%AD%A5%E1%A5%E2%A5%EA%A5%A2%A5%AF%A5%BB%A5%B9%CA%FD%CB%A1
- http://msdn.microsoft.com/ja-jp/library/4ca6d5z7(v=vs.80).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-4