Creating a PowerBasic DLL for BlitzMax

BlitzMax Forums/BlitzMax Tutorials/Creating a PowerBasic DLL for BlitzMax

Kanati(Posted 2006) [#1]
This should cover a few of the oddities that I ran into while creating a dll for use with BlitzMax using PowerBasic 8.01 (though any version from 6 up should work).

The Blitz Code to access the dll is detailed elsewhere but here's a quick rundown:
Global ThisDLL = LoadLibraryA("ThisDLL")
'Note that you do not add the .DLL to the end of the library name

Global ThisFunction:Byte Ptr(S1:Byte Ptr) = GetProcAddress(ThisDLL, "ThisFunction")


At that point you can use the functions in your program.



Passing strings to and from the DLL.

You will need to pass a BYTE PTR to the dll and accept it as a BYREF variable as ASCIIZ. Likewise when returning a string to blitzmax you need to pass back a memory pointer to a byte array (or more commonly a cstring).

Example of Powerbasic Function:
FUNCTION Strings CDECL ALIAS "Strings" (BYREF s1 AS ASCIIZ, BYREF s2 AS ASCIIZ) EXPORT AS DWORD
  DIM RSLT AS STRING
  RSLT = S1 + S2
  FUNCTION = STRPTR(RSLT)
END FUNCTION      


The Blitz code to access this function and get the result:

Local bpString1:Byte Ptr
Local bpString2:Byte Ptr
Local bpResult:Byte Ptr
Local sString1:String
Local sString2:String
local sResult:String

sString1 = "This is a test..."
bpString1 = sString1.ToCString()
sString2 = "This is another test..."
bpString2 = sString2.ToCString()

bpResult = Strings(bpString1, bpString2)

sResult.FromCString(bpResult)

FreeMem bpResult
FreeMem bpString1
FreeMem bpString2

Print sResult


The above calls Strings to concatenate two strings to one. You need to use FreeMem to avoid having a memory leak and should not use .ToCString() inside the function call as a parameter for the same reason. This is a problem with blitzmax that Mark has stated will be looked at and hopefully added to the automatic garbage collector.


Passing and returning numbers:

FUNCTION Numbers ALIAS "Numbers" (BYVAL i1 AS LONG, BYVAL i2 AS LONG) EXPORT AS LONG
  FUNCTION = i1 + i2
END FUNCTION


This is pretty straight forward excepting that powerbasic is not like most basic variants in that it's default method of passing variables is BYREF. So you HAVE to specify BYVAL to pass the variable by value instead of reference.

The only other issue is that you make sure you match up the variable types correctly. Check the documentation closely to make sure your variable types are exact. In this case Blitz's INT and PowerBasic's LONG types match as they are both 32 bit signed integers.

The blitz code:

Local t:Int

t = Numbers(23, 89)

Print t


Much more straight forward than strings, so you might want to wrap some blitz functions around dll functions that take strings as parameters or returns them.


Once you get past the variable issues, dll creation in powerbasic is pretty easy.


assari(Posted 2006) [#2]
thanks for sharing


Panno(Posted 2006) [#3]
well Kanati this is great !
thx


Russell(Posted 2006) [#4]
Nice tut!

PowerBasic has some nice features (I have version 6), but I stopped upgrading because I got tired of waiting for them to add REAL graphics commands. I guess they don't understand the MASSIVE potential for games development. (That's good for BRL, I suppose, because PowerBasic has lots of things to like about it including inline ASM, small/fast code and...dare I say it...excellent documentation). The bad part is that it costs hundreds of dollars, charges extra for everything and only gets updated about once a year (or less).

Anyway...

I just use PureBasic to make DLLs now - It's way cheaper, also has inline asm, produces small/fast code and only costs about $60US...and updates are free. It's documentation is better than Max's, but only just a little ;)