Top / .NET備忘録 / 14.【注意】VarPtr関数 / 03.さらに注意事項

VarPtr 関数の他に ObjPtr 関数と StrPtr 関数を実装しましたが、この2つの関数、とくに StrPtr については注意しなければならないことがあります

というのは、VB6.0 においては String 型の変数を他の変数にコピーすると、新しくインスタンスを作成しますが、.NET においては作成されません。

【VB6】

Sub Main()
    Const C1 As String = "AAAAAAA"
    Dim S1 As String
    Dim S2 As String
    S1 = C1
    S2 = S1
    Debug.Print "C1 StrPtr = " & StrPtr(C1)
    Debug.Print "S1 StrPtr = " & StrPtr(S1)
    Debug.Print "S2 StrPtr = " & StrPtr(S2)
End Sub

結果
C1 StrPtr = 7227104
S1 StrPtr = 149970196
S2 StrPtr = 149973276

【VB.NET】

Sub Main()
    Const C1 As String = "AAAAAAA"
    Dim S1 As String
    Dim S2 As String
    S1 = C1
    S2 = S1
    Debug.Print("C1 StrPtr = {0}", StrPtr(C1).DangerousGetHandle())
    Debug.Print("S1 StrPtr = {0}", StrPtr(S1).DangerousGetHandle())
    Debug.Print("S2 StrPtr = {0}", StrPtr(S2).DangerousGetHandle())
End Sub

結果
C1 StrPtr = 39660744
S1 StrPtr = 39660744
S2 StrPtr = 39660744

つまり、S2 を使って API から値を受け取ると、S1 はおろか、定数である C1 まで書き換えられてしまいます。

【VB.NET】

Imports VB6Control
Imports System.Runtime.InteropServices

Public Class StrPtrTestForm

    <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
    Private Shared Function GetWindowText(hWnd As IntPtr, lpString As SafeHandle, nMaxCount As Integer) As Integer
    End Function

    Private Shared Function FromWin32String(ByVal value As String) As String
        Dim pos As Integer = value.IndexOf(ChrW(0))
        If pos < 0 Then
            Return value
        Else
            Return value.Substring(0, pos)
        End If
    End Function

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Const C1 As String = "AAAAAAAAAAAAAAAAAA"
        Dim S1 As String
        Dim S2 As String
        S1 = C1
        S2 = S1
        GetWindowText(Me.Handle, StrPtr(S2), S2.Length)
        Debug.Print("C1={0}", FromWin32String(C1))
        Debug.Print("S1={0}", FromWin32String(S1))
        Debug.Print("S2={0}", FromWin32String(S2))
    End Sub

End Class

結果
C1=StrPtrTestForm
S1=StrPtrTestForm
S2=StrPtrTestForm

デバッガで C1 をウォッチすると書き換わったように見えないのがカオスです。

StrPtrTest.gif



トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   最終更新のRSS
Last-modified: 2017-05-31 (水) 09:57:38 (26d)