|
2019/06/07(Fri) 11:30:36 編集(投稿者)
※Console.WriteLine 時にスペルミスしていたので、コードを再整理
■No91214 (まる さん) に返信 > VB6ではなぜ上手くいき
参照設定で配列を渡す場合は、SAFEARRAY や VARIANT で丸ごと受け渡していたので、 配列の先頭要素を参照渡しする方法は経験が無いのですよね…。
Declare な方では、先頭要素を参照渡しする方法も良く使っていたのですが。
> cpp,hpp,odlそれぞれに記載されたAAAの宣言を編集する必要がある、という事でしょうか…?
C++ 側は専門外なので、こっちは何とも。
>>> Dim objHandle As GCHandle = GCHandle.Alloc(shtArray(0),GCHandleType.Pinned) >>> Dim intPinned As Intptr = objHandle.AddrOfPinnedObject()
intPinned をどうやって DLL に渡すのかが読み取れなかったのですが、 先頭要素だけを Pinned しても駄目だと思います。
Imports System.Runtime.InteropServices Module Module1
Sub Main() Dim bin As Byte() = {&H11, &H22, &H33, &H44, &H55, &H66, &H77, &H88, &H99, &HAA, &HBB, &HCC, &HDD, &HEE, &HFF} 'Dim bin As Byte() = {&HFE, &HDC, &HBA, &H98, &H76, &H54, &H32, &H1F, &HED, &HCB, &HA9, &H87, &H65, &H43, &H21}
Console.WriteLine("=== bin (サンプルデータ) ===") Dump(bin)
' bin よりも少し大きめに確保 Dim ary1 As Short() = Enumerable.Repeat(&H1234S, 20).ToArray() Dim ary2 As Short() = Enumerable.Repeat(&H1234S, 20).ToArray()
Console.WriteLine("=== Short 配列全体を Pinned した場合 ===") Dim h1 As GCHandle = GCHandle.Alloc(ary1, GCHandleType.Pinned) CopyMemory(bin, h1) h1.Free()
Console.WriteLine("=== Short 配列の先頭要素だけを Pinned した場合 ===") Dim h2 As GCHandle = GCHandle.Alloc(ary2(0), GCHandleType.Pinned) CopyMemory(bin, h2) h2.Free()
Console.WriteLine("=== ary1 は書き換わっている ===") Dump(ary1)
Console.WriteLine("=== ary2 は書き換わらない ===") Dump(ary2)
Console.ReadLine() End Sub
Sub CopyMemory(source As Byte(), h As GCHandle) Dim t As Type = h.Target.GetType() Console.WriteLine("Target Is {0} / {1}", TypeName(h.Target), t.Name) Dim et As Type = If(t.IsArray(), t.GetElementType(), t) Dim sz As Integer = Marshal.SizeOf(et) Dim p As IntPtr = h.AddrOfPinnedObject() Console.WriteLine("p => 0x{0:X} (address)", p)
Console.WriteLine("--- コピー前 ---", p) Console.WriteLine("p = 0x{0:X}", Marshal.ReadInt64(p)) For n = 0 To 3 Console.WriteLine("p[{0}] = 0x{1:X}", n, Marshal.PtrToStructure(IntPtr.Add(p, n * sz), et)) Next
Marshal.Copy(source, 0, p, source.Length)
Console.WriteLine("--- コピー後 ---", p) Console.WriteLine("p = 0x{0:X}", Marshal.ReadInt64(p)) For n = 0 To 3 Console.WriteLine("p[{0}] = 0x{1:X}", n, Marshal.PtrToStructure(IntPtr.Add(p, n * sz), et)) Next End Sub
Sub Dump(Of T As Structure)(ary As T()) Dim bytes As Integer = Marshal.SizeOf(Of T)() Console.Write(" Len={0}:", bytes * ary.Length) Dim fmt As String = " {0:X" & CStr(2 * bytes) & "}" For Each x As T In ary Console.Write(fmt, x) Next Console.WriteLine() End Sub End Module
|