Dynamically Loaded Libraries

BlitzMax Forums/BlitzMax Module Tweaks/Dynamically Loaded Libraries

N3m(Posted 2005) [#1]
I tried to load load libraries dynamically ( at runtime ) and here is what i got. I have createt a module wich hides the os specific stuff and provides the same interface on linux, windows and macos.
(there is no macos support at the moment because i have no mac and i have no idea how to do it. but the modul is writen to be extendable and so you can add other "loaders" easily. )

Here is the download:
http://www.strohmahz.com/bmax/dynload.zip

There is only the source in the zipfile so you need an correctly installed GCC/MinGW to build it. Just unzip it into your blitzmax mod folder and then:
bmk makemods pub.dynload
bmk makemods -r  pub.dynload 


You can use the modul thisway:
Rem
   OOP Interface
End Rem

Local lib:TLibrary = TLibrary.Load("lib") 'Pfad zur lib oder nur lib wenn sich die lib in einem
                          'Verzeichnis befindet in dem das Betriebsystem danach sucht.

Local func:Int ( a:Double, b:String )      'Prototyp der Function die man verwenden will.

lib.GetFunction ( "functionname", Varptr func )

Print func ( 4, "fubar" )              'Function verwenden.

Rem
   Non OOP Interface
End Rem


Local lib = LoadLibrary ( "lib" )

Local func:Int ( a:Double, b:String )

GetFunction ( lib, "functionname", Varptr func )

Print func ( 4, "fubar" ) 


So here are two sensless examples :]

Linux:
Strict

Local lib = LoadLibrary ( "/lib/libm.so.6" )

Local cosine:Double ( z:Double )

GetFunction ( lib, "cos", Varptr cosine )

Print cosine ( Pi / 2 )  + "  = "  + cos ( 90 )
Print cosine ( 0 )  + "  = "  + cos ( 0 )
Print cosine ( Pi )  + "  = "  + cos ( 180 ) 


Windows:
Strict

Local lib:TLibrary = TLibrary.Load ( "kernel32.dll" )

Local Beep ( freq, duration )

lib.GetFunction ( "Beep", Varptr Beep )

Beep ( 200, 2000 ) 


n3m


MrCredo(Posted 2005) [#2]
i said this in other forum. this don't work each time on my machine...

i think this is blitzbasic-fault... or nobody can help me to solve this problem... i see no way to use dynamicaly DLL's in blitzmax...

http://www.blitzbasic.com/Community/posts.php?topic=44022


Russell(Posted 2005) [#3]
It would be nice if we could get a finitive 'how-to' on this from Mark, Skidracer or someone else equally qualified, don't you agree?

I think it is possible, but what is the proper way? Or if it isn't possible now, when?

Russell

p.s. This almost certainly destroy cross-platform capability in this area, though. Don't think DLLs are supported on the Mac :(


N(Posted 2005) [#4]
Don't think DLLs are supported on the Mac :(


I believe shared objects are (modules/shared libraries/DLL for other names, I suppose). If there wasn't some similar way to do this, we'd be pretty screwed.

Edit: Works fine here, tested it on my Xiphias DLL.


Drago(Posted 2005) [#5]
MrCredo, if the function isn't exported from the DLL properly it will cause blitz to crash after a few calls.

Easiest way is to have this in your c++ programs header.
#ifdef _DLLEXPORTS
#define BBDECL extern "C" _declspec(dllexport)
#else
#define BBDECL extern "C" _declspec(dllimport)
#endif

#define FALSE   0
#define TRUE	1
#define BBCALL _stdcall
#define BBvoid BBDECL void BBCALL
#define BBint BBDECL int BBCALL
#define BBfloat BBDECL float BBCALL
#define BBchar BBDECL char BBCALL
#define BBcnstchar BBDECL const char * BBCALL
#define BBbool BBDECL bool BBCALL



N(Posted 2005) [#6]
I use this:
// When building, when importing it's dllimport
#define XAPI __declspec (dllexport)
#define XCALL _cdecl

XAPI xEngine* XCALL xInitEngine(void);


So, cdecl obviously works in this case. Not sure about stdcall.


Drago(Posted 2005) [#7]
I use stdcall, and I know it works, since I left a program running overnight calling the same function again and again. :)