C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

ログ内検索
  • キーワードを複数指定する場合は 半角スペース で区切ってください。
  • 検索条件は、(AND)=[A かつ B] (OR)=[A または B] となっています。
  • [返信]をクリックすると返信ページへ移動します。
キーワード/ 検索条件 /
検索範囲/ 強調表示/ ON (自動リンクOFF)
結果表示件数/ 記事No検索/ ON
大文字と小文字を区別する

No.91223 の関連記事表示

<< 0 >>
■91223  Re[3]: VB.NETからC++のdll関数への参照渡しについて
□投稿者/ 魔界の仮面弁士 -(2019/06/06(Thu) 15:20:06)
    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
記事No.91199 のレス /過去ログ157より / 関連記事表示
削除チェック/



<< 0 >>

パスワード/

- Child Tree -