获取byref字符串引用的内存地址

时间:2011-03-15 16:00:30

标签: .net vb.net pointers

我正在尝试更有效的方法来生成表单。我的实验可以直接通过类引用链接字符串和其他类型,并使用它来更新原始值而无需任何强类型代码。

我一直在使用GCHandle.AddrOfPinnedObject来获取字符串的内存地址,但是它给出了字符串数据的内存地址,而不是我需要更改的字符串类/引用以允许我使用这种方法。

我知道字符串是不可变的并且无法更改(Actualy,你可以,但不推荐),但我不想更改实际的字符串,而是更改对它的引用(字符串对象)。

是否有其他方法可以获取字符串对象引用的地址?

一些示例代码:

Private oTestperson As New Person

Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    ' Create the form
    AddText("Name", oTestperson.Name)
    AddText("Phone", oTestperson.Phone)
    AddText("Address", oTestperson.Address)

End Sub

Public Sub AddText(ByVal Title As String, ByRef sValue As String)

    Dim oGCHandle As System.Runtime.InteropServices.GCHandle
    Dim oInputItem As New InputItem

    ' This does not do the job, as it only returns the address of the string data, not the reference to the string class
    oGCHandle = System.Runtime.InteropServices.GCHandle.Alloc(CType(sValue, Object), System.Runtime.InteropServices.GCHandleType.Pinned)
    oInputItem.Pointer = oGCHandle.AddrOfPinnedObject()
    oGCHandle.Free()

    ' Store data
    oInputItem.ID = GetID()
    oInputItem.Type = InputTypes.Text
    oInputItem.BaseValue = sValue
    If Not Request.Form(oInputItem.ID) Then oInputItem.Value = Request.Form(oInputItem.ID)
    If oInputItem.Value Is Nothing Then oInputItem.Value = sValue

    ' Save in collection
    InputItems.Add(oInputItem)

End Sub

Private Sub linkbuttonSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles linkbuttonSave.Click
    Save()
End Sub

Public Sub Save()

    Dim oTest As New Person
    Dim oGCHandle As System.Runtime.InteropServices.GCHandle
    Dim NewStrPointer As IntPtr

    ' Check if something has been changed, in that case update the origional value
    For Each oInputItem As InputItem In InputItems
        If oInputItem.Value <> oInputItem.BaseValue Then
            oGCHandle = GCHandle.Alloc(oInputItem.Value, GCHandleType.Pinned)
            NewStrPointer = oGCHandle.AddrOfPinnedObject()
            oGCHandle.Free()

            ' This fails as oInputItem.Pointer is the address of the string data, not the string class
            Marshal.WriteInt32(oInputItem.Pointer.ToInt32, NewStrPointer.ToInt32)

        End If
    Next

End Sub

Private InputItems As New ArrayList

Private Class Person
    Public Property Name As String
    Public Property Phone As String
    Public Property Address As String
End Class

Public Enum InputTypes As Integer
    Text = 0
End Enum

Public Class InputItem

    Public Property ID As String
    Public Property BaseValue As Object
    Public Property Value As Object
    Public Property Type As InputTypes = 0
    Public Property Pointer As IntPtr

End Class

2 个答案:

答案 0 :(得分:0)

批准的方法是使用反射,它会更容易,CLR将能够确保您不会在整个地方捣毁物体。

答案 1 :(得分:0)

你的方法有点像C ++ / VB6 / 90年代晚期,但努力的是10! :)

System.Reflection上阅读iterating classesDataBinding了解绑定(数据)类到GUI,Serialization用于读/写类。使用WPF将进一步简化任务到接近虚无(注意WPF可以通过ElementHost在WinForms中使用。