Announcement

Collapse
No announcement yet.

Pass array to Dll?

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

  • Pass array to Dll?

    Hello,

    How could a Delphi EXE pass an array to a PB DLL? I'll need to have a couple of large two dimensional arrays and a bitmap stored in the DLL, but defined and sent by the Delphi program. The only way I know of is to use something like this:
    Code:
      Set_Array_Size 500,500    (500 by 500 array)
      For X_Index = 1 to 500
       For Y_Index = 1 to 500
        Value = Array(X_Index,Y_Index)
        Set_Array_Value X,Y,Value
       Next
      Next
    Is there a way to pass/copy an array to the PB DLL in one operation, rather thandoing this one element at a time, with thousands of function calls?

    Thanks,
    Todd Wasson
    Performance Simulations
    Drag Racing and Top Speed
    Prediction Software http://PerformanceSimulations.Com


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




    [This message has been edited by Todd Wasson (edited January 29, 2001).]
    Todd Wasson
    http://PerformanceSimulations.Com
    PowerBasic Racing Simulator (October 2007 clip - 15.1MB wmv file) http:http://www.performancesimulations.co...m-GenIV-12.wmv

  • #2
    Hello,

    How about you pass a pointer to the array along with two values for the size of the array:

    MyFunctionInDll(pointerToArray AS LONG PTR, arrayXSize AS LONG, arrayYSize AS LONG)

    You will then need to look up how pointers work and how to use pointer off sets.

    If you would like a small example email me at [email protected]

    Hope that helps,
    Colin Schmidt

    ------------------
    Colin Schmidt & James Duffy, Praxis Enterprises, Canada

    PS: Todd: I'm building a 76 Buick Skyhawk with a 3.8 Buick Turbo with about 350h

    [This message has been edited by Colin Schmidt (edited January 29, 2001).]

    Comment


    • #3
      Thanks, Colin.

      I'd like to see your example. Building the Skyhawk, huh? About time! I wonder how close AqueTree will be Will email you.

      Thanks again,

      ------------------
      Todd Wasson
      -------------
      Performance Simulations
      Drag Racing and Top Speed
      Prediction Software
      http://PerformanceSimulations.Com
      Todd Wasson
      http://PerformanceSimulations.Com
      PowerBasic Racing Simulator (October 2007 clip - 15.1MB wmv file) http:http://www.performancesimulations.co...m-GenIV-12.wmv

      Comment


      • #4
        To recap Colin's reply, you can use the same strategy as passing an array from VB to PB.

        Pass the 1st element of the array by reference (BYREF) to the DLL function (along with a couple of variables to tell the code how big the array bounds are).

        Then in the DLL, receive the 1st parameter as a BYVAL DWORD, then use DIM..AT to declare a PB array over the top of the Delphi array.

        From there, you can reference the array with normal PowerBASIC array code rather than dealing with pointers.

        I'm not a Delphi programmer so I have no idea how to ensure that the 1st array element is passed BYREF - I'm sure you'll figure that one out!

        However, the PB code would look something like this:
        Code:
        FUNCTION MyFunc(BYVAL arr AS DWORD, x AS LONG, y AS LONG) EXPORT AS LONG
          DIM PBarray(1:x,1:y) AS LONG AT arr
          PBarray(1,1) = 123456&
          ARRAY SORT PBarray(1) FOR x     ' 1st dimension sort
          ARRAY SORT PBarray(y + 1) FOR x ' 2nd dimension sort
          FUNCTION = -1 ' success!
        END FUNCTION
        I hope this helps!


        ------------------
        Lance
        PowerBASIC Support
        mailto:[email protected][email protected]</A>
        Lance
        mailto:[email protected]

        Comment


        • #5
          Thanks, Lance. We posted at exactly the same time, how often does that happen?
          I'll need to try out the code and read more about these things in the help files, as this code looks Greek to me!

          Thanks again,


          ------------------
          Todd Wasson
          -------------
          Performance Simulations
          Drag Racing and Top Speed
          Prediction Software
          http://PerformanceSimulations.Com
          Todd Wasson
          http://PerformanceSimulations.Com
          PowerBasic Racing Simulator (October 2007 clip - 15.1MB wmv file) http:http://www.performancesimulations.co...m-GenIV-12.wmv

          Comment


          • #6
            Please, if you can, refrain from laughing at the attempt below! The PBMAIN function here simulates the Delphi EXE by creating an array (DelphArray). Then, it calls the simulated DLL function to store it as Pbarray. Obviously, I'm doing this wrong, but do you see what I'm trying to do?
            Code:
            #COMPILE EXE
            DEFSNG A-Z
            '
            FUNCTION MyFunc(BYVAL arr AS DWORD,x AS LONG,y AS LONG) AS LONG
            LOCAL TEXT AS STRING
              DIM PBarray(1:x,1:y) AS LONG AT arr
              PBarray(1,1) = 123456&
              ARRAY SORT PBarray(1) FOR x     ' 1st dimension sort
              ARRAY SORT PBarray(y + 1) FOR x ' 2nd dimension sort
              FUNCTION = -1 ' success!
            END FUNCTION
            '
            FUNCTION PBMAIN()
            'Delphi EXE makes an array to pass to DLL function
            DIM DelphArray(1:10,1:10) AS LONG
            FOR x = 1 TO 10
                FOR y = 1 TO 10
                    DelphArray(x,y) = x + y
                NEXT
            NEXT
            'Now, the simulated Delphi EXE calls my DLL function, storing data
            'in PBarray (the DLL storage array).  This is obviously not the right way   [img]http://www.powerbasic.com/support/forums/smile.gif[/img]
            MyFunc DelphArray,10,10
            END FUNCTION
            Am I way off here? Must be!

            Thanks,

            ------------------
            Todd Wasson
            -------------
            Performance Simulations
            Drag Racing and Top Speed
            Prediction Software http://PerformanceSimulations.Com



            [This message has been edited by Todd Wasson (edited January 29, 2001).]
            Todd Wasson
            http://PerformanceSimulations.Com
            PowerBasic Racing Simulator (October 2007 clip - 15.1MB wmv file) http:http://www.performancesimulations.co...m-GenIV-12.wmv

            Comment


            • #7
              Heh! The problem with trying this technique all in one module is that the target function declaration is known to PB, so the compiler is expecting you to pass the 1st element BYVAL. When we are using this in a DLL format, we get the result that we want since there is no parameter checking other than a suitable declaration in the Delphi code.

              So, in order to make this work within one PB module, you'll have to override the typechecking on the calling code, thus:
              Code:
              MyFunc BYVAL VARPTR(DelphArray(1,1)), 10, 10 
              ' The (1,1) is needed so we pass the address of the 1st element, not the address of the array descriptor.
              ------------------
              Lance
              PowerBASIC Support
              mailto:[email protected][email protected]</A>
              Lance
              mailto:[email protected]

              Comment


              • #8
                Well, you have it already! I'm assuming you don't need the example. If so however just email me. However, it will be late tomorrow afternoon before I get to it.

                Colin

                ------------------
                Colin Schmidt & James Duffy, Praxis Enterprises, Canada
                [email protected]

                Comment


                • #9
                  Thanks, guys Here's a little benchmark comparison between your method and the one I was considering. Quite an improvement in speed this way!

                  Code:
                  #COMPILE EXE
                  DEFSNG A-Z
                  GLOBAL PBarray2() AS LONG
                  
                  FUNCTION InputLoopMethod(BYVAL x AS LONG,BYVAL  y AS LONG, BYVAL value AS LONG) AS LONG
                  PBarray2(x,y) = value
                  END FUNCTION
                  
                  FUNCTION MyFunc(BYVAL arr AS DWORD,x AS LONG,y AS LONG) AS LONG
                  LOCAL TEXT AS STRING
                    DIM PBarray(1:x,1:y) AS LONG AT arr
                    ARRAY SORT PBarray(1) FOR x     ' 1st dimension sort
                    ARRAY SORT PBarray(y + 1) FOR x ' 2nd dimension sort
                    FUNCTION = -1 ' success!
                  'For small 10x10 or so sized arrays, view the list here
                  '  FOR x_index = 1 TO x
                  '      FOR y_index = 1 TO y
                  '  TEXT$ = TEXT$ + FORMAT$(PBarray(x_index,y_index),"##  ")
                  '      NEXT
                  '  NEXT
                  '  MSGBOX TEXT$
                  END FUNCTION
                  
                  FUNCTION PBMAIN()
                  'Delphi EXE makes an array to pass to DLL function
                  DIM Num_X_Elements AS LONG
                  DIM Num_Y_Elements AS LONG
                  Num_X_Elements = 10000
                  Num_Y_Elements = 100
                  DIM DelphArray(1:Num_X_Elements,1:Num_Y_Elements) AS LONG
                  FOR x = 1 TO Num_X_Elements
                      FOR y = 1 TO Num_Y_Elements
                          DelphArray(x,y) = x + y
                      NEXT
                  NEXT
                  MSGBOX "Array initialization complete.  Press 'ok' to continue.",,"Ready"
                  'Now, the Delphi EXE calls my DLL function, storing data
                  'in PBarray.
                  ''This is used only if "MyFunc" is in a DLL
                  'MyFunc DelphArray,10,10
                  ''Otherwise, use this:
                  t0 = TIMER
                  MyFunc BYVAL VARPTR(DelphArray(1,1)), Num_X_Elements, Num_Y_Elements
                  t1 = TIMER
                  ElapsedTime1 = t1 - t0
                  TEXT$ = STR$(ElapsedTime1)
                  MSGBOX "Method 1 elapsed time: " + TEXT$,,"Test 1 of 2"
                  
                  
                  '''Try input loop method:
                  DIM Value AS LONG
                  DIM PBarray2(1:x,1:y) AS LONG
                  t0 = TIMER
                  FOR x = 1 TO Num_X_Elements
                      FOR y = 1 TO Num_Y_Elements
                          value = DelphArray(x,y)
                          InputLoopMethod x,y,value
                      NEXT
                  NEXT
                  t1 = TIMER
                  ElapsedTime2 = t1 - t0
                  TEXT$ = STR$(ElapsedTime2)
                  MSGBOX "Method 2 elapsed time: " + TEXT$,,"Test 2 of 2"
                  IF ElapsedTime1 <> 0 THEN
                    MSGBOX "Method 1 was " + STR$(ElapsedTime2 / ElapsedTime1) + " times faster in this test:0)   Thanks to Lance and Colin!",,"Hooray!"
                  END IF
                  END FUNCTION
                  ------------------
                  Todd Wasson
                  -------------
                  Performance Simulations
                  Drag Racing and Top Speed
                  Prediction Software http://PerformanceSimulations.Com

                  [This message has been edited by Todd Wasson (edited January 31, 2001).]
                  Todd Wasson
                  http://PerformanceSimulations.Com
                  PowerBasic Racing Simulator (October 2007 clip - 15.1MB wmv file) http:http://www.performancesimulations.co...m-GenIV-12.wmv

                  Comment

                  Working...
                  X