CallDll
[Result] = CallDll(DLLNumber, FunctionName$, [Params])
 
Parameters:

    DLLNumber = The DLL number
    FunctionName$ = The name of the function you want to call
    [Params] = Specifies between 0 and 64 (optional) parameters that can be passed to a function
Returns:

    [Result] = Holds the return value of the DLL function (optional)
 

     With CallDll you can call a function within a DLL that either returns an Integer value or returns nothing. Use CallDLL#() or CallDll$() to return floats or strings from an external dll function call.


      Calling functions from external machine code DLL's gives us the flexibility to expand PlayBASIC beyond the standard abilities the developers have included for us. However, while they've tried to make this as user friendly as possible, DLL's can be a complex subject matter to wrap ones programming brain around, in particular for those new to the programming.

      One thing that can make using 3rd party DLL's difficult, is we'll often need to find information about what functions a DLL's of interest contains. For system DLL's this is generally easy, there's literally thousands of websites that have information about system DLL's, it's the DLL's that are written by other people that might be lacking information about what functions they include and what parameters the functions need and what calling convention they use. All of which can sometimes be difficult to work out as not all DLL's developers release this information to the public, let alone 'instructions' on how to use the functions correctly.




What's a Function?


      First things first, from here on we're going to assume the reader is familiar with PlayBASIC functions (See Function) and PlayBASIC data types such and Integer, Float & String. If your not, then it might be best to first get up to speed with those, as we're going to assume the reader has some grass roots understanding from here on in.




What's a DLL?


      A DLL's is short for Dynamic Link Library in Windows programmer speak. They're really nothing more than a chunk of executable code with an interface attached to it. The purpose of a DLL's is to share common functionality between different programs. The idea is that common groups code can be bundled together into focused dll's, which programmers can then use a DLL functions within their programs. So a DLL can be used a single program or by many programs at once.




How Do I Call DLL Functions ?


      Well, in order to call a function from any DLL, we first need to load that DLL into memory. We do that using the LoadDLL command (or LoadNewDll()) function. Once a DLL has been loaded, we can then call our requested function from that DLL using a CallDll function, which we do using the name of the function as a string and our DLL index as integer.

Example:

           CallDll( MyDll, "MyFunctionName")

      What happens is the CallDll operation searches with the loaded DLL index for that function name, if it exists, it returns a pointer to the function name internally which it ultimately calls. This transfers execution to the DLL until the function completes it's task, whatever that might be. The CallDll operation includes various error checks to try and ensure that we're not calling a none existant function (which would be bad) and should return a runtime error if a such a thing occurs.


Example:

  
  
; Load this pretend DLL into DLL slot 1
  LoadDll "MyTest.dll"1
  
  CallDll1,  "MyFunction"  )
  
  



      When though this mock up example, providing the LoadDLL command can find the DLL in our programs folder, and that dll includes function named "MyFunction" then this would call that function.





Passing Parameters to DLL Functions:


      In our previous example the function we called didn't have any input parameters. Which is fairly unusual, as the majority of DLL functions you'll be calling, will require parameters of some type. Unfortunately PlayBASIC isn't able to work out what parameters a function requires for you. So in this regard in becomes very important the programmer understand what parameters the function requires and what data types each should be.

      You might have noticed that in PlayBASIC user functions you can generally pass integers in place of floats (and vice versa) into functions, this is NOT the case with DLL functions however. If you attempt to pass an integer and the function expects a float, then you should expect it to behave erratically, and possibly even crash. So care is needed in this regard.

      To pass parameters all we do is list them after the Function Name in our CallDll expression. So if know our function that we wanted to call as called "AddIntegers" and that function expects two integer paramters. Then a call to that function might like look this.


Example:

           CallDll( MyDll, "AddIntegers" , Integer1, Integer2 )


      Assuming our function called AddIntegers takes two integer parameters which then adds them together, then we could assume it'd return an integer result also. So a usage example could look like this.

  
  
; Load this pretend DLL into DLL slot 1
  LoadDll "MyPretendTestDll.dll"1
  
; Call our function and store the returned value in the Result variable
  Result =CallDll1,  "AddIntegers" ,  100200  )
  
; Display the
  Print Result
  
  





Supported Parameters Data Types:


      CallDll supports PlayBASIC Integer, Float, String, Pointers and passing Typed Variables (by handle). One thing you should be aware of is the more complex the data type the more work that the PlayBASIC runtime needs to do when passing that data out.




Parameter Passing Method:


      When PlayBASIC calls external DLL functions, the basic numeric data types like integer and floating point values are passed in as 32bit format respectively. Strings and Typed variables require some intervention prior to be being passed to the DLL, this is because internally strings and types are held in a unique format inside PlayBASIC, a form that doesn't exist outside of PlayBASIC.

Strings

      When we pass a PlayBASIC string to a function, the CallDll will compute a pointer to the first character in the string and then pass that through. The data in the string will be null terminated, which just means that it has a zero at the end of character data, you might know this format as a C string, which is fairly common format for strings.

      It's important to understand that when a string is passed, the string data isn't a copy of the internal PlayBASIC string. This means that if the function you call, modifies the string then the string data inside PB will be modified also. Now depending upon the function, this may or may not be desirable, in particular if the DLL atempts to delete or write to the string outside of it's allocated memory, then PlayBASIC won't appreciate that. In other words, it'll probably crash. If you have problems you suspect occur from this, then you can allocate some memory yourself and store the string data in that and pass a pointer in it's place.



Typed Variables

      All type structures created inside PlayBASIC are housed in special containers which are managed by the PlayBASIC runtime. Now just like strings, this is a unique PlayBASIC only implementation, so if we need to pass these out to external functions when we need to convert the data into a more common format. That format being a bare bones C structure. C structures are just blocks of grouped fields, but just like Types in PlayBASIC.

      The current implementation of the CallDll only supports passing type variable handles. What happens is the typed data is converted to a temporary structure and a pointer to the newly created copy of the structure is made available to the function you're calling. After the CallDll executes it copies the data back from the temporary structure back into the PlayBASIC version. So it looks to the user this data is being passed as a pointer to the internal type, but it's actually a copy. The only exception are with PlayBASIC strings, which are handled just like individual string parameters. When a PlayBASIC string is converted to a pointer, within the structure.





FACTS


      * You can only use CallDll() with standard DLLs. See NewAx for ActiveX/COM DLLs

      * Use GetDllCallExist to check if a particular function name exists with a DLL. While DLL functions generally have text names, they can sometimes have manageed names when exported. Which just means that whatever language the programmer of the DLL used to create the DLL, they tool appended some characters to the name during export.


      * Use DllCallConv to change Calling Convention PlayBASIC will use to call a function within a DLL.







Mini Tutorial:


     Not available

 
Related Info: CallDLL# | CallDLL$ | CallFunction | DllCallConv | FunctionIndex | GetDLLCallExist | LoadDLL :
 


(c) Copyright 2002 - 2024 - Kevin Picone - PlayBASIC.com