获取的按地址字符串引用的内存地址 [英] Get the memory address of a byref string reference
问题描述
我尝试用更有效的方法来生成表格。我的实验进入的可能性通过类引用链接字符串,和其他类型的,直接和使用它没有任何强类型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屋!