CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Jul 2002
    Location
    England
    Posts
    163

    Angry Passing an Array of User Defined Types

    Ok, here's the problem first. I'd post the code, but it is quite hefty. Ill do so later if noone can help me with this.

    I am writing some functions based around API calls such as GetLogicalDriveStrings and GetDriveType and so on.
    I want to return more than one peice of information about each drive, whilst maintaining a nice coder friendly method to do it. My thought was this. A user type called DriveInformation that held 3 variables: Letter, VolumeName and DriveType. A function gets all the drives on a system, and the information about them, and put this into an array.
    It then passes the array back to the function that called that called it. Boom, VB doesn't like this and the program falls over.

    Anyone ever try something like this? Can you give me a hand.

    REMEMBER, I HAVE NO PROBLEM WITH THE ARRYA OF UDT's, I HAVE PROBLEMS PASSING IT FROM ONE FUNCTION TO THE OTHER.

    PS. Telling me to move to another language is not helpful
    Finite

    "If a cat always lands on its feet, and a peice of bread always lands butter side down, if you strap a peice of bread butter side up to the back of a cat, will it hover?"

  2. #2
    Join Date
    Nov 2002
    Location
    Baby Land
    Posts
    646
    You can pass the pointer to the variable containing the UDT, as long as you don't pass this variable to another computer you can use CopyMemory to return the pointer back to UDT structure

    Note for array of UDT you have to Declare your own VarPtr function like so :

    Private Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" (Ptr() As Any) As Long
    This function return the address of the first element of your array

    Example:

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

    SomeSub(UDTPtr as long)
    'Copy it back to UDT
    dim tUDT as YourUDT

    copymemory tUDT, byval UDTPTR, len(tUDT)
    'Do some calculation

    'copy the result back
    copymemory byval UDTptr,tUDT,len(tUDT)
    end sub

    in the calling sub use the same way to convert ptr back to UDT

    Another way is to use a string variable to hold all the structure's data delimited with a unique character then in the calling sub just split the string back to its components
    Last edited by Luthv; May 11th, 2003 at 05:30 PM.

  3. #3
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    Udt and arrays and byRef

    'Legal: You can modify the values
    'Legal: You can modify dimension
    'Illegal: you cannot redim., redim preserve or erase if you passed
    ' a cell of the array in the function where you want to redim
    'Illegal: you cannot redim, redim preserve or erase if you're inside
    a With ...end with block and you've just accessed a single cell
    value...

    'Legal: within same module, you can pass arrays of Udt by ref.
    Thus you do not need to have a "return value" of Udts: you will
    modiofy same parameter passed.
    'Illegal: you cannot pas same udt through modules: you will have
    to declare it in a class of a Dll with instancing higher than public
    not creatable. And you will have to use early binding in your
    standard exe to be able to declare a variable of tipe of the one
    you created in class

    'ie:
    Your class module: in a project of type dll called "pTheUdt"
    Option Explicit

    Public Type ThisUdt
    Names As String
    Numbers As Long
    End Type
    '---------------------------
    'Your exe standard:
    Dim myUdt() As pTheUdt.ThisUdt
    '-----------


    'Normal code inside a single form can do what you said:
    Code:
    Option Explicit
    Private Type ThisUdt
       Names As String
       Numbers As Long
    End Type
    Dim myUdt() As ThisUdt
    Private Sub Command1_Click()
    
    
    ReDim myUdt(3)
    Dim retvar As Boolean
    retvar = theUdtFunction(myUdt)
    MsgBox "Last:" & UBound(myUdt)
    End Sub
    Private Function theUdtFunction(ByRef AUdt() As ThisUdt) As Boolean
       MsgBox UBound(AUdt)
       ReDim Preserve AUdt(UBound(AUdt) + 1)
       theUdtFunction = the12nd_UdtFunction(AUdt)
    End Function
    Private Function the12nd_UdtFunction(ByRef AUdt() As ThisUdt) As Boolean
       MsgBox UBound(AUdt)
       ReDim Preserve AUdt(UBound(AUdt) + 1)
    End Function
    More detail on your crash?
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  4. #4
    Join Date
    Apr 2003
    Posts
    1,755

    Smile

    You can return a UDT array from the function. Take a look at my code
    Code:
    Private Type myUDT
       x As Long
       y As Long
       z As Long
    End Type
    
    Private Function UDTProc() As myUDT()
       Dim arrUDT() As myUDT
       ReDim arrUDT(10) As myUDT
       arrUDT(0).x = 100
       arrUDT(10).x = 200
       UDTProc = arrUDT
    End Function
    
    Private Sub Form_Load()
       Dim retUDT() As myUDT
       retUDT = UDTProc
       MsgBox UBound(retUDT)
    End Sub
    I tested it and it worked well. I also placed the UDT and function in a module and it also worked well

    Hope it will help you
    Last edited by Cimperiali; May 14th, 2003 at 03:00 PM.

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