Results 1 to 31 of 31

Thread: Return an object(late-bind) by giving an object pointer - How?

  1. #1

    Thread Starter
    Fanatic Member jian2587's Avatar
    Join Date
    Aug 2000
    Location
    I bet u need a fusion powered shuttle to reach my place...
    Posts
    963

    Return an object(late-bind) by giving an object pointer - How?

    Let's say I've an object pointer.
    I want a function that returns an object to me by simply giving it
    an object pointer. Then I'll set it to an Object variable.
    Then I'll use its function the late-bind way.
    Is this possible?
    ASM,C,C++,BASIC,VB,JAVA,VBS,HTML,ASP,PHP,mySQL,VB.NET,MATLAB
    Programming is fun, but only if you're not on a tight deadline
    So I consider all those working engineers sad people

    VB FTP class
    3 page PHP crash course
    Crash Course on DX9 Managed with VB.NET covering basics till terrain creation

  2. #2
    Frenzied Member moinkhan's Avatar
    Join Date
    Jun 2000
    Location
    Karachi, Pakistan
    Posts
    2,011
    How can u use pointers in VB?
    I used Structuer pointer like this

    Dim mvRect As Rect
    RtlMoveMemory mvRect, ByVal lParam, Len(mvRect)

    I don't know what to do with Objects... Well..There's no object pointer in VB

  3. #3
    The Devil crptcblade's Avatar
    Join Date
    Aug 2000
    Location
    Quetzalshacatenango
    Posts
    9,091
    Originally posted by moinkhan
    Well..There's no object pointer in VB
    ObjPtr.

    But CopyMemory doesn't work with them.
    Laugh, and the world laughs with you. Cry, and you just water down your vodka.


    Take credit, not responsibility

  4. #4
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    But CopyMemory doesn't work with them.
    Could you elaborate a little more on this statement please?

    Here is a simplistic example:
    VB Code:
    1. ' cMyTest Class
    2. ' Just a simple class to test using ObjPtr and CopyMemory.
    3. Option Explicit
    4.  
    5. Private Type MyUDT
    6.     ID As Long
    7.     Description As String
    8. End Type
    9.  
    10. Private mudtData As MyUDT
    11.  
    12. Public Property Get ID() As Long
    13.  
    14.     ID = mudtData.ID
    15.  
    16. End Property
    17.  
    18. Public Property Let ID(ByVal Value As Long)
    19.  
    20.     mudtData.ID = Value
    21.  
    22. End Property
    23.  
    24. Public Property Get Description() As String
    25.  
    26.     Description = mudtData.Description
    27.  
    28. End Property
    29.  
    30. Public Property Let Description(ByVal Value As String)
    31.  
    32.     mudtData.Description = Value
    33.  
    34. End Property
    VB Code:
    1. ' frmMyTest form
    2. ' Just a simple form to test using ObjPtr and CopyMemory.
    3. Option Explicit
    4.  
    5. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    6.  
    7. ' The object that we will be instantiating and setting its state.
    8. Private mobjSrc As cMyTest
    9.  
    10. ' The object that we will not be instantiating but setting its state
    11. ' using CopyMemory.
    12. Private mobjDest As cMyTest
    13.  
    14. Private Sub Command1_Click()
    15.  
    16.     ' Show what we have in the Source instance.
    17.     With mobjSrc
    18.         Debug.Print .ID
    19.         Debug.Print .Description
    20.     End With
    21.  
    22. End Sub
    23.  
    24. Private Sub Command2_Click()
    25.  
    26.     Dim lngSource As Long
    27.  
    28.     ' Obtain the Source instance's address in memory
    29.     lngSource = ObjPtr(mobjSrc)
    30.  
    31.     ' Copy the state of Source to create and set the state of Dest.
    32.     ' Note: We have not instantiated the Destination.
    33.     CopyMemory mobjDest, lngSource, 4
    34.  
    35.     ' Show what we have in the Destination instance.
    36.     With mobjDest
    37.         Debug.Print .ID
    38.         Debug.Print .Description
    39.     End With
    40.  
    41. End Sub
    42.  
    43. Private Sub Form_Load()
    44.  
    45.     ' Create the Source instance and set its state.
    46.     Set mobjSrc = New cMyTest
    47.     With mobjSrc
    48.         .ID = 1001
    49.         .Description = "This is a test"
    50.     End With
    51.  
    52. End Sub
    It may not work for complex classes encapsulating other objects (although I will be testing this more to confirm), but using ObjPtr and CopyMemory does work (with at least simple objects).

  5. #5
    The Devil crptcblade's Avatar
    Join Date
    Aug 2000
    Location
    Quetzalshacatenango
    Posts
    9,091
    I didn't think that it would always work, like you said, with objects encapsulating objects, and so forth. Granted I have never really found the need to do such a thing, so I haven't invested much time in testing it. But if it can be done, then it can be done. What can I say?

    Laugh, and the world laughs with you. Cry, and you just water down your vodka.


    Take credit, not responsibility

  6. #6
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    I've completed some testing on the subject and have found that it will work for encapsulated objects and to jian2587's original question, it will work with late-binding.
    VB Code:
    1. ' cMyTestSub
    2. Option Explicit
    3.  
    4. Private Type MySubUDT
    5.     SubID As Long
    6.     SubDescription As String
    7. End Type
    8.  
    9. Private mudtData As MySubUDT
    10.  
    11. Public Property Get SubID() As Long
    12.  
    13.     SubID = mudtData.SubID
    14.  
    15. End Property
    16.  
    17. Public Property Let SubID(ByVal Value As Long)
    18.  
    19.     mudtData.SubID = Value
    20.  
    21. End Property
    22.  
    23. Public Property Get SubDescription() As String
    24.  
    25.     SubDescription = mudtData.SubDescription
    26.  
    27. End Property
    28.  
    29. Public Property Let SubDescription(ByVal Value As String)
    30.  
    31.     mudtData.SubDescription = Value
    32.  
    33. End Property
    VB Code:
    1. ' cMyTest
    2. Option Explicit
    3.  
    4. Private Type MyUDT
    5.     ID As Long
    6.     Description As String
    7. End Type
    8.  
    9. Private mudtData As MyUDT
    10.  
    11. Private mobjSub As cMyTestSub
    12.  
    13. Private mcolSubs As Collection
    14.  
    15. Public Property Get ID() As Long
    16.  
    17.     ID = mudtData.ID
    18.  
    19. End Property
    20.  
    21. Public Property Let ID(ByVal Value As Long)
    22.  
    23.     mudtData.ID = Value
    24.  
    25. End Property
    26.  
    27. Public Property Get Description() As String
    28.  
    29.     Description = mudtData.Description
    30.  
    31. End Property
    32.  
    33. Public Property Let Description(ByVal Value As String)
    34.  
    35.     mudtData.Description = Value
    36.  
    37. End Property
    38.  
    39. Public Property Get EncapsulatedObject() As cMyTestSub
    40.  
    41.     Set EncapsulatedObject = mobjSub
    42.  
    43. End Property
    44.  
    45. Public Property Set EncapsulatedObject(ByVal Instance As cMyTestSub)
    46.  
    47.     Set mobjSub = Instance
    48.  
    49. End Property
    50.  
    51. Public Property Get Subs() As Collection
    52.  
    53.     Set Subs = mcolSubs
    54.  
    55. End Property
    56.  
    57. Private Sub Class_Initialize()
    58.  
    59.     Set mcolSubs = New Collection
    60.  
    61. End Sub
    VB Code:
    1. ' frmMyTest
    2. Option Explicit
    3.  
    4. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    5.  
    6. Private mobjTest1 As cMyTest
    7. Private mobjTest2 As Object
    8.  
    9. Private Sub Command1_Click()
    10.  
    11.     Dim objsub As cMyTestSub
    12.  
    13.     With mobjTest1
    14.         Debug.Print "Source " & .ID
    15.         Debug.Print "Source " & .Description
    16.         With .EncapsulatedObject
    17.             Debug.Print "    Source Enc Sub " & .SubID
    18.             Debug.Print "    Source Enc Sub " & .SubDescription
    19.         End With
    20.         For Each objsub In .Subs
    21.             Debug.Print "    Source Subs " & objsub.SubID
    22.             Debug.Print "    Source Subs " & objsub.SubDescription
    23.         Next
    24.     End With
    25.  
    26. End Sub
    27.  
    28. Private Sub Command2_Click()
    29.  
    30.     Dim lngSource As Long
    31.     Dim lngDest As Long
    32.     Dim objsub As cMyTestSub
    33.  
    34.     lngSource = ObjPtr(mobjTest1)
    35.  
    36.     CopyMemory mobjTest2, lngSource, 4
    37.  
    38.     With mobjTest2
    39.         Debug.Print "Dest " & .ID
    40.         Debug.Print "Dest " & .Description
    41.         With .EncapsulatedObject
    42.             Debug.Print "    Dest Enc Sub " & .SubID
    43.             Debug.Print "    Dest Enc Sub " & .SubDescription
    44.         End With
    45.         For Each objsub In .Subs
    46.             Debug.Print "    Dest Subs " & objsub.SubID
    47.             Debug.Print "    Dest Subs " & objsub.SubDescription
    48.         Next
    49.     End With
    50.  
    51. End Sub
    52.  
    53. Private Sub Form_Load()
    54.  
    55.     Dim objsub As cMyTestSub
    56.  
    57.     Set mobjTest1 = New cMyTest
    58.     With mobjTest1
    59.         .ID = 1001
    60.         .Description = "This is a test"
    61.     End With
    62.  
    63.     Set mobjTest1.EncapsulatedObject = New cMyTestSub
    64.     With mobjTest1.EncapsulatedObject
    65.         .SubID = 500
    66.         .SubDescription = "This is a sub test"
    67.     End With
    68.  
    69.     mobjTest1.Subs.Add mobjTest1.EncapsulatedObject
    70.  
    71.     Set objsub = New cMyTestSub
    72.     With objsub
    73.         .SubID = 501
    74.         .SubDescription = "This is another sub test"
    75.     End With
    76.     mobjTest1.Subs.Add objsub
    77.  
    78. End Sub

  7. #7
    Addicted Member
    Join Date
    Feb 2003
    Posts
    237
    one other thing to test is what happens when the
    source object goes out of scope...

    the ref count is not incremented with copymemory
    so if you hung onto just the pointer to long, or the
    dest object you could run into problems with invalid
    pointer in some situations

    you could get around this by copymemory to a temp
    object then returning another one taken from the
    temp with set= to increment the ref count (assuming
    valid pointer passed in)
    Free Code, papers, tools, and more

    http://sandsprite.com

  8. #8

    Thread Starter
    Fanatic Member jian2587's Avatar
    Join Date
    Aug 2000
    Location
    I bet u need a fusion powered shuttle to reach my place...
    Posts
    963
    Nice codes!
    I haven't tested the code...but from what I see, apart from some
    nice and good codes, is that the codes looks more like creating a
    new copy of object than returning an object to me. But anyway
    I'd be glad to know how to do that! Lots of thanks to rlwhealdon!

    and dzzie, nice advice! I never knew that...

    And one more question, if the object I want to refer is out of my
    own process, is it possible to use rlwhealdon's method?
    ASM,C,C++,BASIC,VB,JAVA,VBS,HTML,ASP,PHP,mySQL,VB.NET,MATLAB
    Programming is fun, but only if you're not on a tight deadline
    So I consider all those working engineers sad people

    VB FTP class
    3 page PHP crash course
    Crash Course on DX9 Managed with VB.NET covering basics till terrain creation

  9. #9

    Thread Starter
    Fanatic Member jian2587's Avatar
    Join Date
    Aug 2000
    Location
    I bet u need a fusion powered shuttle to reach my place...
    Posts
    963
    Apparently I was wrong.

    It did return an object to me instead of creating a new one.

    I just found out that it's actually changing the destination object
    to point to the source object.

    If the source object is out of my process, can I refer it?
    Or is there a workaround for this?
    ASM,C,C++,BASIC,VB,JAVA,VBS,HTML,ASP,PHP,mySQL,VB.NET,MATLAB
    Programming is fun, but only if you're not on a tight deadline
    So I consider all those working engineers sad people

    VB FTP class
    3 page PHP crash course
    Crash Course on DX9 Managed with VB.NET covering basics till terrain creation

  10. #10
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    I don't believe that you can set an instance of an Object variable to an instance of another class/object just by its pointer. To achieve this, you will need to create a copy using the methods demonstrated.

    With something like:
    VB Code:
    1. Set mobjTest2 = ObjPtr(mobjTest1)
    You will get a Type Mismatch error because your are telling VB to set an instance of an Object to the value of a Long.

    I have not tested this across processes, but my gut is telling me that since each process is running its own address space, that the memory address returned by ObjPtr in one process will not relate to the same memory address in another process. I could be wrong, and will need to test it to confirm.

  11. #11

    Thread Starter
    Fanatic Member jian2587's Avatar
    Join Date
    Aug 2000
    Location
    I bet u need a fusion powered shuttle to reach my place...
    Posts
    963
    Well yes that's what I mean.
    But it's not really creating another copy, it's still pointing to the
    source object.
    So if I modify the destination object, the source object will be
    modified as well, because both is pointing to the very same object

    And BTW, thx rlwhealdon! u've been gr8 hlp!

    and thx for doing research on that!
    ASM,C,C++,BASIC,VB,JAVA,VBS,HTML,ASP,PHP,mySQL,VB.NET,MATLAB
    Programming is fun, but only if you're not on a tight deadline
    So I consider all those working engineers sad people

    VB FTP class
    3 page PHP crash course
    Crash Course on DX9 Managed with VB.NET covering basics till terrain creation

  12. #12
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    Another issue to point out using this method is that you will not be able to explicitly garbage collect the instances of the objects.
    VB Code:
    1. Private Sub Form_Unload(Cancel As Integer)
    2.  
    3.     Set mobjTest1 = Nothing
    4.     Set mobjTest2 = Nothing
    5.  
    6. End Sub
    Will procedure an "Unhandled Exception" stating that the memory at such-and-such an address could not be referenced.

  13. #13
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    I use copy memory all the time with objects...it works fine...

    U get the pointer by using ObjPtr Then pass the long value ino:
    VB Code:
    1. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
    2.  
    3. Public Function PtrObj(ByVal Pointer As Long) As Object
    4. Dim objObject   As Object
    5.     CopyMemory objObject, Pointer, 4&
    6.     Set PtrObj = objObject
    7.     CopyMemory objObject, 0&, 4&
    8. End Function

    Woka

  14. #14
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    I use copy memory all the time with objects...it works fine...
    ...Woka
    Yes, we have demonstrated that CopyMemory using the ObjPtr works.

    However, the following was not something that I considered as a method for garbage collection.
    VB Code:
    1. CopyMemory objObject, 0&, 4&
    Thank you for that.

    jian2587's outstanding question is though:
    "Will this work across processes?"

  15. #15
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    VB Code:
    1. Option Explicit
    2.  
    3. Private Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
    4. Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    5. Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
    6. Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
    7. Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    8. Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    9. Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
    10. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
    11.  
    12. Private Const PROCESS_VM_READ        As Long = &H10
    13.  
    14. Private Type mtypDataStruct
    15.     Pointer  As Long
    16.     Length   As Long
    17. End Type
    18.  
    19. Dim marBuffer()     As Byte
    20. Dim mudtStruct      As mtypDataStruct
    21.  
    22. Public Function ReadMemory(ByVal ProcessID As Long, ByVal Pointer As Long) As Byte()
    23. Dim lngProcessHWND      As Long
    24. Dim lngBytesRead        As Long
    25. Dim arBuffer()          As Byte
    26. Dim udtStruct           As mtypDataStruct
    27.     lngProcessHWND = OpenProcess(PROCESS_VM_READ, False, ProcessID)
    28.     If lngProcessHWND Then
    29.         Call ReadProcessMemory(lngProcessHWND, ByVal Pointer, ByVal VarPtr(udtStruct), LenB(udtStruct), lngBytesRead)
    30.         ReDim arBuffer(0 To udtStruct.Length - 1) As Byte
    31.         Call ReadProcessMemory(lngProcessHWND, ByVal udtStruct.Pointer, ByVal VarPtr(arBuffer(0)), udtStruct.Length, lngBytesRead)
    32.         Call CloseHandle(lngProcessHWND)
    33.         ReadMemory = arBuffer
    34.         CloseHandle lngProcessHWND
    35.     End If
    36. End Function
    37.  
    38. Public Function ReadMemoryFromHWND(ByVal hwnd As Long, ByVal MemAddr As Long) As Byte()
    39. Dim lngProcessID        As Long
    40.     GetWindowThreadProcessId hwnd, lngProcessID
    41.     ReadMemoryFromHWND = ReadMemory(lngProcessID, MemAddr)
    42. End Function
    43.  
    44. Public Function SendByteArray(ByVal hwnd As Long, ByVal ByteArray As String) As Long
    45. Dim lngRet      As Long
    46.     marBuffer = ByteArray
    47.     With mudtStruct
    48.         .Length = UBound(marBuffer) + 1
    49.         .Pointer = VarPtr(marBuffer(0))
    50.     End With
    51.     SendByteArray = SendMessage(hwnd, CUSTOM_MESSAGE, GetCurrentProcessId, mudtStruct)
    52.     Erase marBuffer
    53. End Function
    54.  
    55. Public Sub PostByteArray(ByVal hwnd As Long, ByVal ByteArray As String)
    56.     marBuffer = ByteArray
    57.     With mudtStruct
    58.         .Length = UBound(marBuffer) + 1
    59.         .Pointer = VarPtr(marBuffer(0))
    60.     End With
    61.     Call PostMessage(hwnd, CUSTOM_MESSAGE, GetCurrentProcessId, VarPtr(mudtStruct))
    62. End Sub
    63.  
    64. Public Function PtrObj(ByVal Pointer As Long) As Object
    65. Dim objObject   As Object
    66.     CopyMemory objObject, Pointer, 4&
    67.     Set PtrObj = objObject
    68.     CopyMemory objObject, 0&, 4&
    69. End Function
    70.  
    71. Public Sub KillProcess(ByVal ProcessName As String)
    72.     TerminateEXE ProcessName
    73. End Sub
    Well using the above I read Byte arrays from different processes...I am sure that this can be modified slightly so return an object...will it work...??? Hmmmm dunno...give it a go

    Woka

  16. #16

  17. #17
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    Garbage collection???

    Woka
    Yes, that is my general term for cleaning up after one's self.

    As I stated in a previous post in this thread. Once I've created a new reference to an object based on its memory address, issuing a:
    VB Code:
    1. Set objObject = Nothing
    results in an "Unhandled Exception".
    If I remove the statement, then the exception is not thrown.

    I personally don't like having things left around waiting for VB to determine that they have gone out of scope.

    When you posted your first response in this thread, you included a line that in essense, is cleaning up (setting the value of the object instance to 0&, aka Null, aka Nothing) after itself.
    VB Code:
    1. CopyMemory objObject, 0&, 4&
    If I have mis-interpretted the intent of this statement, then please by all means set me straight.

  18. #18
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    That line destroys the object...however, since it's private to that function it will get destroyed when the function looses scope anyways...but using that line destroys it anyways...

    Woka

  19. #19

  20. #20
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    Exactly my point. It does destroy the object instance.

    I was thanking you for a method to do so in a manner that didn't produce an unhandled exception.

    And congratulations on your promotion to "God".

    Don't take it personally if I don't kneel down and provide you with subservient piety though.

  21. #21
    Addicted Member
    Join Date
    Feb 2003
    Posts
    237
    technically it doesnt really "destroy" the object

    put msgbox in class_terminate and watch when
    it pops

    with copy memory you arent creating a new class
    or destroying one, you are getting a valid reference
    to the com object from its pointer value.

    so its not cleanup in the set = nothing sense
    because the ref count was never incremented

    when you copymemory obj, 0 , 4
    you are just removing the reference
    to the valid class in the tmp variable

    if the objptr was not 0 , then when the
    variable goes out of scope, vb would automatically
    call the equilivent set obj= nothing to decrement its
    ref count

    if the object we to nolonger exist then you would get
    the invalid memory error.
    Free Code, papers, tools, and more

    http://sandsprite.com

  22. #22
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    But it "is" cleaned up in the sense that testing the object variable against Nothing returns true. It's state is now the equivelant of the object variable had I issued the "Set ObjectInstance = Nothing" statement.
    VB Code:
    1. CopyMemory mobjTest1, 0&, 4&
    2. CopyMemory mobjTest2, 0&, 4&
    3.  
    4. MsgBox mobjTest1 Is Nothing
    5. MsgBox mobjTest2 Is Nothing
    Both display True.

    I understand that VB will eventually handle this for you. I however, am very anal. If I open it, then I try to close it. If I create it, then I try to destroy it. Regardless of whether or not I "need" to.

    Actually, I am quite suprised that a simple thank you to Wokawidget for inadvertantly feeding my anal retentiveness, has exploded in the manner that it has.

    I don't believe that I have misunderstood what has been communicated here. If any of my posts have given the impression to the contrary, then I guess that I need to work more on my communication skills.

  23. #23
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Well the Terminate event is not going to get fired is it, considering there is still a reference to that object...

    Create 2 objects...set one = to a valid object, use the PtrObj method I posted either, destroy the 1st object using SET , then Use the copy memory API to destroy the 2nd object and the terminate event will get fired...

    So it does destroy the object

    It works...

    Did anyone manage to copy an object from another process using the code I provided???
    Woka

    PS Cheers...I have always been god, but just not let on

  24. #24
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    Did anyone manage to copy an object from another process using the code I provided???
    No, I hadn't gotten to that yet.

  25. #25
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Hahahahahaha...Bugger
    I feel stupid now
    VB Code:
    1. CopyMemory objObject, 0&, 4&
    Does't work...Hahahahahahahahaha
    Somewhere along the line my code has been mashed. I'm glad you spotted that....however I am confused where my original code has gone too

    Anyways, the function should be:
    VB Code:
    1. Public Function PtrObj(ByVal Pointer As Long) As Object
    2. Dim objObject   As Object
    3.     CopyMemory objObject, Pointer, 4&
    4.     Set PtrObj = objObject
    5.     CopyMemory ObjPtr(objObject), 0&, 4&
    6. End Function
    The destination has to be the POINTER of the object, and not the object itself...just passing the object causes a memory leak

    Hope that helps...

    Oh, here'#s an example to prove it works...

    Woka
    Attached Files Attached Files

  26. #26

  27. #27
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    I think you had it right the first time. Your modified version, copying 0& to the pointer of the object results in an unhandled exception, where the previous version did not.

  28. #28
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Change the code in that form, in the zip I posted, to:
    VB Code:
    1. Option Explicit
    2.  
    3. Private objOne      As clsWoof
    4. Private objTwo      As clsWoof
    5.  
    6. Private Sub Command1_Click()
    7.     Set objOne = New clsWoof
    8.     objOne.Username = "Growling Weasel"
    9.     Set objTwo = PtrObj(ObjPtr(objOne))
    10.     MsgBox ObjPtr(objTwo)
    11.     Set objOne = Nothing
    12.     CopyMemory ObjPtr(objTwo), 0&, 4&
    13. End Sub
    Suggests that the object DOESN'T get destroyed...I am not God

    However
    VB Code:
    1. CopyMemory ObjPtr(objTwo), 0&, 4&
    Does allow the object to be destroyed once the function is was defined in gets destroyed...
    The CopyMemory only destroys the pointer to the object and not the contents on the object....Hmmmmmmm

    How can you find the length of an Object in bytes???
    Can't find any API for it

    Woka

  29. #29
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Originally posted by rlwhealdon
    I think you had it right the first time. Your modified version, copying 0& to the pointer of the object results in an unhandled exception, where the previous version did not.
    Errr....so my ZIP file I posted gives you an error??? I don't get an error....but the object gets destroyed when the sub ends...
    Just passing the object to copymemory does not terminate the object when the sub finishes, but when the process gets terminated...passing the pointer of the object terminates the object when, and ONLY when, the scope of the object runs out, ie when the form is unloaded, or when the sub finishes
    Hmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm...

    I thought I had this wrapped up months ago....yet this thread has proved otherwise...Hmmmm cool! back to the drawing board...

    Woka

  30. #30
    Addicted Member
    Join Date
    Mar 2003
    Location
    Minneapolis, MN
    Posts
    151
    Your project doesn't give me any errors. The one that I had been using for this thread throws an unhandled exception when I try to use:
    VB Code:
    1. CopyMemory ObjPtr(mobjTest2), 0&, 4&
    I don't receive the exception if I just use:
    VB Code:
    1. CopyMemory mobjTest2, 0&, 4&
    Here's my test project.
    The remmed out stuff dealt with the my tests on the encapsulated objects.
    Attached Files Attached Files

  31. #31

    Thread Starter
    Fanatic Member jian2587's Avatar
    Join Date
    Aug 2000
    Location
    I bet u need a fusion powered shuttle to reach my place...
    Posts
    963
    Yes, an object is only destroyed when it's out of scope.
    But it's also destroyed when all reference to it is destroyed.

    Woka,
    if u add in Set objTwo = Nothing as well, the object will get
    destroyed b4 the scope runs out, in this case, the form.
    because all references to the object(both objOne and objTwo) is
    destroyed.

    I realized that if you create an object through CopyMemory,
    u've to destroy it through CopyMemory Obj, 0&, 4&
    and not Set Obj = Nothing

    The same thing if you create an object by Set Obj = ObjSrc.
    U've to Set Obj = Nothing instead of CopyMemory Obj, 0&, 4&

    Because u create ObjTwo by Set ObjTwo = objObject, VB knows
    there's another reference to it, and thus even Set ObjOne =
    Nothing wouldn't destroy the object.

    Different thing if u point the object urself through CopyMemory.
    VB doesn't know it and lots errors crop up when u try to Set it to
    Nothing.
    ASM,C,C++,BASIC,VB,JAVA,VBS,HTML,ASP,PHP,mySQL,VB.NET,MATLAB
    Programming is fun, but only if you're not on a tight deadline
    So I consider all those working engineers sad people

    VB FTP class
    3 page PHP crash course
    Crash Course on DX9 Managed with VB.NET covering basics till terrain creation

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