Announcement

Collapse
No announcement yet.

Help passing UDT Array from VB to PBDLL

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help passing UDT Array from VB to PBDLL

    Here is the VB Code I have:

    Code:
    Public Declare Function PerVac Lib "VacPer.dll" Alias "PERVAC" (Employee() As EmployeeStruct) As Long
    
    Type PeriodStruct
        Jan As Long
        Feb As Long
        Mar As Long
        Apr As Long
        May As Long
        Jun As Long
        Jul As Long
        Aug As Long
        Sep As Long
        Oct As Long
        Nov As Long
        Dec As Long
    End Type
    
    Type EmployeeStruct
         SSN As String * 9
         PersonalEarned As PeriodStruct
         PersonalUsed As PeriodStruct
         VacationEarned As PeriodStruct
         VacationUsed As PeriodStruct
    End Type
    
    ..
    
    sub TEST()
         Dim Employee(1 To 3000) As EmployeeStruct
         Employee(1).SSN = "123456789"
         a& = PerVac(Employee())
         Debug.Print Employee(1).SSN
         Debug.Print Employee(2).SSN
    end sub
    Example PB Code

    Code:
    #compile dll "C:\winnt\system32\vacper.dll"
    
    #INCLUDE "C:\PBDLL60\Samples\Vb32\VBAPI32.INC" 
    TYPE PeriodStruct DWORD
        Jan AS LONG
        Feb AS LONG
        Mar AS LONG
        Apr AS LONG
        May AS LONG
        Jun AS LONG
        Jul AS LONG
        Aug AS LONG
        Sep AS LONG
        Oct AS LONG
        Nov AS LONG
        Dec AS LONG
    END TYPE
    
    TYPE EmployeeStruct DWORD
         SSN AS STRING * 9
         PersonalEarned AS PeriodStruct
         PersonalUsed AS PeriodStruct
         VacationEarned AS PeriodStruct
         VacationUsed AS PeriodStruct
    END TYPE
    
    FUNCTION PerVac(Info AS DWORD) EXPORT AS LONG
        msgbox "Start"
        LOCAL l  AS LONG
        LOCAL u  AS LONG
        LOCAL vb AS DWORD
        l  = vbArrayLBound(Info, 1)
        u  = vbArrayUBound(Info, 1)
        vb = vbArrayFirstElem(Info)
    
        DIM Employee(1 TO u) AS EmployeeStruct AT vb
    
        MSGBOX "lBound: " & STR$(l)
        MSGBOX "ubound: " & STR$(u)
        MSGBOX "First Elem: " & STR$(vb)
        MSGBOX Employee(1).SSN                                
    end function
    When running this code, I get the following message Boxes:

    "Powerbasic - Start"
    "lbound: 1"
    "ubound: 3000"

    with the message box "First Element:" I get a crazy number which makes no sense
    when I do a messagebox Employee(1).SSN I get a random number

    Any ideas?

    Thanks


    ------------------
    -Greg
    -Greg
    [email protected]
    MCP,MCSA,MCSE,MCSD

  • #2
    I think that when you define the parameter as Employee() on the VB end, you're
    telling VB to pass something like an array handle in VB's format, rather than
    the actual data. Try defining the parameter "ByVal pEmployee As Long" on the VB
    end, and pass VarPtr(Employee(LBound(Employee))) to the routine. That should
    allow your PowerBASIC routine to properly map the VB data to the PB array.


    ------------------
    Tom Hanlin
    PowerBASIC Staff

    Comment


    • #3
      Tom,

      I tried what your suggested and I did infact pass the address
      of the array but as soon as I tried to access it within PB
      it crashes. Any more ideas?

      ------------------
      -Greg
      -Greg
      [email protected]
      MCP,MCSA,MCSE,MCSD

      Comment


      • #4
        I think you need DWORD alignment on EmployeeStruc.

        That STRING * 9 is probably throwing it off.

        MCM

        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Michael,

          Maybe I'm missing something but I think I already have DWORD
          alignment on EmployeeStruct

          ------------------
          -Greg
          -Greg
          [email protected]
          MCP,MCSA,MCSE,MCSD

          Comment


          • #6
            Ok, I thought about what Micheal said, and I already did have
            DWORD alignment but I thought I would change the:

            SSN as string * 9 to
            SSN as long


            After doing that, everything worked fine. What would cause this?

            ------------------
            -Greg
            -Greg
            [email protected]
            MCP,MCSA,MCSE,MCSD

            Comment


            • #7
              VB does not use DWORD alignment. It uses natural alignment. I would put in a filler type of 1 or 3 bytes after SSN. Or better yet place SSN at the end of the type.

              Added later: By the way, what version of VB are you using?
              VB3, VB4/16 use byte alignment
              VB4/32, VB5 use 'natural' alignment (I have never used VB6)

              Joe


              ------------------


              [This message has been edited by Joseph W Murphy (edited June 30, 2001).]

              Comment


              • #8
                Moving SSN at the end of the type as STRING * 9 doesn't change
                anything. I still get GPF's. But it looks like I will just
                leave the SSN as a LONG. a lot more stable in performance.

                Thanks for everyone's help.

                ------------------
                -Greg
                -Greg
                [email protected]
                MCP,MCSA,MCSE,MCSD

                Comment


                • #9
                  Hi, If your just writing a fast (meaning time to write code
                  not exacution speed) application for your own use and have
                  lots of extra ram (structure size) a quick and dirty
                  trick is to write the VB structure to a ram drive and reading it
                  from PD/DLL. Reading and writing to a file is byte by byte
                  (if openend for bianry) so there's no need to pad
                  or depad the structure in PB or VB. If your writing a new app
                  then line up your structure's but if it's an older app
                  and you need a quick fix till you have time to rewrite the code
                  then this works and is pretty fast since its all in ram. I wish
                  VB (Mircosoft) would be like PB and let you set the boundry of
                  the structure's but till they do we're stuck with the stupid way
                  VB works. The FAQ in this fourm explains all the VB/PB UDT stuff
                  very well.

                  Doug

                  ------------------
                  Doug McDonald
                  KD5NWK
                  www.redforksoftware.com

                  Comment


                  • #10
                    D. McDonald,

                    This application will be installed on 7 or 10 different users.
                    Setting up a RAMDRIVE would not be an option. If I remember
                    correctly don't you have to put that in the CONFIG.SYS?

                    Anyways, I am using DAO for most of the work in VB but there
                    are some things that are SO slow in VB and that is what PB is for.
                    I'm making a PB DLL with SQLTools to do the directy work and
                    returning a UDT Array of all Employee's and there vacation and
                    personal balance's. PB takes about 2 seconds to complete this
                    for all employees. Visual Basic took about 2 second PER employee.


                    ------------------
                    -Greg
                    -Greg
                    [email protected]
                    MCP,MCSA,MCSE,MCSD

                    Comment

                    Working...
                    X