CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    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???

  2. #2
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Modify Object by reference

    It's Private...
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  3. #3
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    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.

  4. #4
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    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.

  5. #5
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Modify Object by reference

    Try +1 in Modify()...

    No compiler here...
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  6. #6
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    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.

  7. #7
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    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.

  8. #8
    Join Date
    Mar 2002
    Location
    Izhevsk, Udmurtia, Russia
    Posts
    930

    Re: Modify Object by reference

    Quote Originally Posted by WoF View Post
    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

  9. #9
    Join Date
    Jul 2001
    Location
    Sunny South Africa
    Posts
    11,283

    Red face Re: Modify Object by reference

    Quote Originally Posted by WoF View Post
    @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

    Quote Originally Posted by Vi2 View Post
    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

  10. #10
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    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...

  11. #11
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    Re: Modify Object by reference

    Quote Originally Posted by WoF View Post
    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.

  12. #12
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    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.

  13. #13
    Join Date
    Mar 2002
    Location
    Izhevsk, Udmurtia, Russia
    Posts
    930

    Re: Modify Object by reference

    Quote Originally Posted by WoF View Post
    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

  14. #14
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    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?

  15. #15
    Join Date
    Jun 2005
    Location
    JHB South Africa
    Posts
    3,772

    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.

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured