获取的按地址字符串引用的内存地址 [英] Get the memory address of a byref string reference

查看:144
本文介绍了获取的按地址字符串引用的内存地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试用更有效的方法来生成表格。我的实验进入的可能性通过类引用链接字符串,和其他类型的,直接和使用它没有任何强类型code键更新原始值。

我用GCHandle.AddrOfPinnedObject得到字符串的内存地址已经,但它给字符串数据,而不是字符串类/引用,我需要改变,以允许我使用这种方式的内存地址。

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

有一些其他的方式来获得一个字符串对象引用的地址?

一些例如code:

 私人oTestperson作为新的人

私人小组的Page_Load(BYVAL发件人为对象,BYVALË作为System.EventArgs)把手Me.Load

    创建表单
    AddText(姓名,oTestperson.Name)
    AddText(手机,oTestperson.Phone)
    AddText(地址,oTestperson.Address)

结束小组

公用Sub AddText(BYVAL标题为String,S值的ByRef作为字符串)

    昏暗oGCHandle作为System.Runtime.InteropServices.GCHandle
    昏暗oInputItem作为新InputItem

    这不会做的工作,因为它仅返回字符串数据的地址,而不是引用的字符串类
    oGCHandle = System.Runtime.InteropServices.GCHandle.Alloc(CTYPE(S值,对象),System.Runtime.InteropServices.GCHandleType.Pinned)
    oInputItem.Pointer = oGCHandle.AddrOfPinnedObject()
    oGCHandle.Free()

    存储数据
    oInputItem.ID =的getId()
    oInputItem.Type = InputTypes.Text
    oInputItem.BaseValue = S值
    如果不是的Request.Form(oInputItem.ID)然后oInputItem.Value =的Request.Form(oInputItem.ID)
    如果oInputItem.Value是没有那么oInputItem.Value = S值

    保存到收藏
    InputItems.Add(oInputItem)

结束小组

私人小组linkbuttonSave_Click(BYVAL发件人为对象,BYVALË作为System.EventArgs)把手linkbuttonSave.Click
    保存()
结束小组

公共Sub保存()

    昏暗oTest作为新人员
    昏暗oGCHandle作为System.Runtime.InteropServices.GCHandle
    昏暗NewStrPointer作为IntPtr的

    检查是否有什么东西被改变,在这种情况下,更新的原始值
    对于每个oInputItem作为InputItem在InputItems
        如果oInputItem.Value<> oInputItem.BaseValue然后
            oGCHandle = GCHandle.Alloc(oInputItem.Value,GCHandleType.Pinned)
            NewStrPointer = oGCHandle.AddrOfPinnedObject()
            oGCHandle.Free()

            这未按oInputItem.Pointer是字符串数据的地址,而不是字符串类
            Marshal.WriteInt32(oInputItem.Pointer.ToInt32,NewStrPointer.ToInt32)

        结束如果
    下一个

结束小组

私人InputItems作为新的ArrayList

私有类人
    公共属性名称作为字符串
    公共属性电话作为字符串
    公共物业地址作为字符串
末级

公共枚举InputTypes作为整数
    文本= 0
结束枚举

公共类InputItem

    公共属性ID作为字符串
    公共属性BaseValue为对象
    公共属性值作为对象
    公共物业类型作为InputTypes = 0
    公共属性指针的IntPtr

末级
 

解决方案

你的做法是有点C ++ / VB 6/90年代末,但10所付出的努力! :)

阅读上的System.Reflection 获得的迭代类中的数据绑定的(数据)类结合GUI和的序列化进行读/写的类。使用WPF将进一步简化任务接近虚无(注WPF可以通过的的ElementHost

I am experimenting with more effective ways to generate forms. My experiments goes into the possibility to link strings, and other types, directly by their class reference and use it to update the original values without any strongly typed code.

I have been using GCHandle.AddrOfPinnedObject to get the memory address of the string, but it gives the the memory address of the string data, not the string class/reference that i need to change to allow me to use this approach.

I am aware that strings are immutable and can not be changed (Actualy, you can, but its not recomended), but I do not want to change the actual strings, but change the reference to it (the string object).

Is there some other way to get the address of a string object reference?

Some example code:

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

解决方案

Your approach is a bit C++/VB6/late 90's, but 10 for the effort! :)

Read up on System.Reflection for iterating classes, DataBinding for binding (data)classes to GUI and Serialization for reading/writing classes. Using WPF will further simplify the task to near nothingness (Note WPF can be used in WinForms via ElementHost.

这篇关于获取的按地址字符串引用的内存地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆