-
August 30th, 2011, 10:05 AM
#1
Modify Object by reference
Hello friends,
I tripped over the following problem:
I write a class module named SomeObject to make an object which has two public variables, a long and a string, as properties:
Code:
'the contents of the class module
Public lVar As Long
Public sVar As String
Then I have a sub which modifies a long and a string which are passed by reference
Code:
Private Sub ModifyByRef(ByRef lv As Long, ByRef sv As String)
lv = 10
sv = "gaga"
End Sub
Now for the problem: I declare an object of the above mentioned type, fill some values in and pass the values to the modifying routine, but no modifying takes place.
Code:
Private Sub btnTestObj_Click()
Dim so As New SomeObject
so.lVar = 1
so.sVar = "abcd"
Print so.lVar, so.sVar
ModifyByRef so.lVar, so.sVar
Print so.lVar, so.sVar
End Sub
There is no error. It seems to be ok to pass the objects properties, which in fact are simple public variables, byref to the modifying sub, also as long as within the sub you can verify single stepping that a modification takes place. Nevertheless, when returning, the old values persist.
Why???
-
August 30th, 2011, 10:11 AM
#2
Re: Modify Object by reference
-
August 30th, 2011, 02:34 PM
#3
Re: Modify Object by reference
Yes. Well, so what? Everything is private within the Form.
Do you think it would work with a public object maybe declared in a module?
I can go and try that.
-
August 30th, 2011, 02:37 PM
#4
Re: Modify Object by reference
Well, alas, your explanation, brief as it is, explains nothing.
I have made so a public SomeObject defined in a module and no change takes place when the ModifyByRef is called.
-
August 30th, 2011, 09:47 PM
#5
Re: Modify Object by reference
Try +1 in Modify()...
No compiler here...
-
August 31st, 2011, 01:50 AM
#6
Re: Modify Object by reference
Hey WoF
Not sure if this what you want....
I made two properties in the class :
Code:
Option Explicit
'the contents of the class module
Private lVar As Long
Private sVar As String
Public Property Get L_Long() As Variant
L_Long = lVar
End Property
Public Property Let L_Long(ByVal vNewValue As Variant)
lVar = vNewValue
End Property
Public Property Get S_String() As Variant
S_String = sVar
End Property
Public Property Let S_String(ByVal vNewValue As Variant)
sVar = vNewValue
End Property
Then, it is easier to manipulate these values from the form. In the Form, I did this :
Code:
Option Explicit
Dim so As New SomeObject
Private Sub Command1_Click()
'Dim so As New SomeObject
' so.lVar = 1
' so.sVar = "abcd"
so.L_Long = 1
so.S_String = "abcd"
' Print so.lVar, so.sVar
Print so.L_Long, so.S_String
ModifyByRef 10, "LADY gaga is Crazy" 'so.lVar, so.sVar
Print so.L_Long, so.S_String
End Sub
Private Sub ModifyByRef(ByRef lv As Long, ByRef sv As String)
' lv = 10
' sv = "gaga"
so.L_Long = lv
so.S_String = sv
End Sub
That was the only way i get this right. I think I'm not very bright or my brain is frozen this morning . But, in any case, I hope it helps.
-
August 31st, 2011, 05:43 AM
#7
Re: Modify Object by reference
@David: Where a simple assignment fails, an increment would not work either.
Nevertheless I tried. Modification of the variable, although passed by ref, is not possible.
@Hannes: No, you simply swapped the premisses. You are passing the new values as arguments and your modify routine simply puts them to the so properties.
It's the other way round. The so properties must be passed to the modifying routine byref.
Fact is, the ModifyByRef() routine is part of a dll and I cannot change it. It expects two longs and will return some values in them to the VB caller. The dll is not aware of the so object.
I only made this sample as simple as possible to show what I mean.
In the object I use simple publics, because I don't need any procedural support, but also when having written get and let procedures like you did, there is no way I can pass a property to be modified byref to another sub, or so it seems.
-
August 31st, 2011, 06:38 AM
#8
Re: Modify Object by reference
Originally Posted by WoF
There is no error. It seems to be ok to pass the objects properties, which in fact are simple public variables, byref to the modifying sub, also as long as within the sub you can verify single stepping that a modification takes place. Nevertheless, when returning, the old values persist.
Why???
Because the VB is able to pass the expression's value by reference. "so.lVar" or 12 or (lVar) are the examples of expression.
Possible solution is
Code:
i=so.lVar: s=so.sVar
ModifyByRef i, s
so.lVar=i: so.sVar=s
With best wishes,
Vita
-----------------------
Russian Software Development Network -- http://www.rsdn.ru
-
August 31st, 2011, 07:05 AM
#9
Re: Modify Object by reference
Originally Posted by WoF
@Hannes: No, you simply swapped the premisses. You are passing the new values as arguments and your modify routine simply puts them to the so properties.
It's the other way round. The so properties must be passed to the modifying routine byref.
Oh, OK - sorry for misunderstanding
Originally Posted by Vi2
Possible solution is
Code:
i=so.lVar: s=so.sVar
ModifyByRef i, s
so.lVar=i: so.sVar=s
Yes, that will work.
If you do this WoF :
Code:
Private Sub Command1_Click()
Dim so As New SomeObject
Dim i As Long
Dim s As String
i = 10
s = "abc"
i = so.lVar: s = so.sVar
Print so.lVar, so.sVar
ModifyByRef i, s
so.lVar = i: so.sVar = s
Print so.lVar, so.sVar
End Sub
It will work.
As you had it :
Code:
Dim so As New SomeObject
so.lVar = 10
so.sVar = "abc"
Print so.lVar, so.sVar
ModifyByRef so.lVar, so.sVar
Print so.lVar, so.sVar
Nothing happens! Why, because you keep passing the same values the whole time. so.lvar and so.svar keeps staying the same, ie. 10 and abc. ModifyByRef simply accepts the values ( 10 and abc ), and does nothing. That is how I understand it.
Sorry for the confusion
-
September 1st, 2011, 07:49 AM
#10
Re: Modify Object by reference
No, Hannes. Look, ModiFyByRef() will modify any passed variable of apropriate type.
Code:
Private Sub ModifyByRef(ByRef lv As Long, ByRef sv As String)
lv = 10
sv = "gaga"
End Sub
Before the call so.lvar is 1 and so.svar is "abcd". They should be modified to 10 and "gaga".
Thing is, with a UDT it would work. Keeping the above modify routine as is and using this code everything is as expected:
Code:
Private Type SomeType
lVar as Long
sVar as String
End Type
Private Sub btnTestObj_Click()
Dim so As SomeType
so.lVar = 1
so.sVar = "abcd"
Print so.lVar, so.sVar
ModifyByRef so.lVar, so.sVar
Print so.lVar, so.sVar
End Sub
vi2's proposal (thanks) is completely right, and I have certainly found that out already.
Only it is not really elegant (sorry). Anyway I had to do that because there seems no other way.
Still I'm curious WHY an object's property, even when being a simple public var, cannot be passed byref to a modifying routine. Seems to be strange...
-
September 1st, 2011, 02:38 PM
#11
Re: Modify Object by reference
Originally Posted by WoF
Still I'm curious WHY an object's property, even when being a simple public var, cannot be passed byref to a modifying routine. Seems to be strange...
I had a similar problem in .NET and fixed it by making the Variables Private and adding Property's to the class..
Code:
Private IlVar As Long
Private IsVar As String
Public Property Get Lvar() As Long
Lvar = IlVar
End Property
Public Property Let Lvar(ByRef value As Long)
IlVar = value
End Property
Public Property Get sVar() As String
sVar = IsVar
End Property
Public Property Let sVar(ByRef value As String)
IsVar = value
End Property
However trying the same 'trick' in VB6 has no effect..
But.. I've since found out that when VB.NET is compiled it is stripped down to the same process that Hannes posted.. (reported about it here)
This is probably the only way to do it..
Code:
TmpL = so.Lvar
TmpS = so.sVar
Call ModifyByRef(TmpL, TmpS)
so.Lvar = TmpL
so.sVar = TmpS
Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
WPF Articles : 3D Animation 1 , 2 , 3
Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.
-
September 2nd, 2011, 03:56 PM
#12
Re: Modify Object by reference
Yes, I'm afraid it is.
It is absolutely unelegant, but it seems to be the only way.
Well, I did modify my code already accordingly.
Only, I would have liked to know why this IS.
But never mind. If noone has an explanation, why public variables of an object cannot be modified by reference, I just have to take it in and live with the solutions we got.
Although it seems quite illogical.
It seems like the mentioned variables are explicitly passed ByVal (although declared ByRef), because they can be modified and used within the ModifyByRef() as you can with any variable passed ByVal.
Last edited by WoF; September 2nd, 2011 at 04:02 PM.
-
September 5th, 2011, 03:16 AM
#13
Re: Modify Object by reference
Originally Posted by WoF
Only, I would have liked to know why this IS.
But never mind. If noone has an explanation, why public variables of an object cannot be modified by reference, I just have to take it in and live with the solutions we got.
Although it seems quite illogical.
It seems like the mentioned variables are explicitly passed ByVal (although declared ByRef), because they can be modified and used within the ModifyByRef() as you can with any variable passed ByVal.
There is no public variables for (1) Object variable (SomeObject variable is also Object variable). Instead of public variable VB adds 2 methods: get and let. For example, next parts of code are equivalent:
Code:
Public lVar As Long
Code:
Private m_lVar As Long
Public Property Get lVar() As Long
lVar = m_lVar
End Property
Public Property Let lVar(ByVal src As Long)
m_lVar = src
End Property
VB makes all actions for first case behind the scene, but its behaviour is the same. VB should get the value from get-property (explicit or generated automatically) and pass this value byref into method.
(1) I think that it will be better: There is no public variables inside Object variable.
Last edited by Vi2; September 5th, 2011 at 03:19 AM.
With best wishes,
Vita
-----------------------
Russian Software Development Network -- http://www.rsdn.ru
-
September 6th, 2011, 05:24 PM
#14
Re: Modify Object by reference
All that means: YOU CANNOT PASS AN OBJECT'S PROPERTY BYREF TO SOME SUB WHICH WANTS TO MODIFY IT! No matter if it is a public var or a a properly implemented property.
Or am I wrong?
-
September 7th, 2011, 01:40 AM
#15
Re: Modify Object by reference
I've been looking up info and thinking about this quite seriously.. and i think i know why...
It might get a little confusing and mixed but try to follow this...
Each Application is allocated to a memory space..
Applications cannot directly modify memory in any other application (including called DLL's). Dont shoot me, You can by finding the Memory location and changing it Indirectly. But there is also the problem of the 64K memory window that cannot be crossed.
Each class object can considered a separate DLL object, as it is the base object of a DLL..
In a class All outside(Public) references are passed ByVal, incase it is accessed across the 64K memory window (Please forgive my terminology)..
And if you followed all that ... By design a Public Class object will not use the Memory pointer's but rather pass the Value, So as not to have Memory Calling issues...
Hope it makes sense.. And if some one can rewrite that better ... PLEASE DO...
Articles VB6 : Break the 2G limit - Animation 1, 2 VB.NET : 2005/8 : Moving Images , Animation 1 , 2 , 3 , User Controls
WPF Articles : 3D Animation 1 , 2 , 3
Code snips: VB6 Hex Edit, IP Chat, Copy Prot., Crop, Zoom : .NET IP Chat (V4), Adv. ContextMenus, click Hotspot, Scroll Controls
Find me in ASP.NET., VB6., VB.NET , Writing Articles, My Genealogy, Forum
All VS.NET: posts refer to VS.NET 2008 (Pro) unless otherwise stated.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|