Dynamically Loaded Libraries

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

Nemesis

Betreff: Dynamically Loaded Libraries

BeitragSa, Feb 19, 2005 1:23
Antworten mit Zitat
Benutzer-Profile anzeigen
So nachdem ich heute ne möglichkeit zum einbinden von Libraries zur laufzeit ( also dlls unter windows ) gefunden habe, habe ich ein Modul geschrieben das das ganze
1. Vereinfachen
2. unter Linux, Windows und MacOS ( noch nicht, da ich keinen mac habe und keinen plan davon habe). einheitlich machen soll.

Also hier ist das Modul:
http://www.strohmahz.com/bmax/dynload.zip

Im zipfile ist im moment nur der source ihr müsst also unter MinGW / GCC installiert haben um das modul zu erzeugen. einfach das zipfile in euren mod-ordner entpachen und danach:

Code: [AUSKLAPPEN]

bmk makemods pub.dynload
bmk makemods -r  pub.dynload


Verwenden Tut man das ganze dann so.

Code: [AUSKLAPPEN]

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 jetzt noch zwei sinnlose beispiele:
(Das von Windows habe ich jetzt nichtmehr getestet weil ich wieder unter Linux bin, ist aber auch nicht sonderlich komplexx Wink )

Linux:
Code: [AUSKLAPPEN]

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:
Code: [AUSKLAPPEN]

Strict

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

Local Beep ( freq, duration )

lib.GetFunction ( "Beep", Varptr Beep )

Beep ( 200, 2000 )
  • Zuletzt bearbeitet von Nemesis am Sa, Feb 19, 2005 11:35, insgesamt einmal bearbeitet

hamZta

Administrator

BeitragSa, Feb 19, 2005 11:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Wow!
gute Arbeit, ist echt praktisch!
Blog.

TheShadow

Moderator

BeitragSa, Feb 19, 2005 15:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Mist wo warst du vor paar Tagen...

hier meine Erkenntnisse:

Code: [AUSKLAPPEN]

Local dll :Int =LoadLibraryA("dummy.dll")
Local addr:Int =Int(GetProcAddress(dll,"test@8"))
Local func:Int (v1:Int, v2:Int)

(Int Ptr(Varptr(func)))[0]=addr

Print dll +" <dummy.dll"
Print addr+" <test@8"
Print func(3,4)


deinen code muss ich mir mal angucken...

Korrekter Link:
http://www.strohmahz.com/bmax/dynload.zip


--EDIT---

Ich muss gestehen, dass deine Lib etwas komplex ist... Meine Methode muss man noch auf XP mit SP2 testen... Da könnte es evtl. Problem mit "NoExecuteBit" geben... aber normal sollte das fruchten...
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
  • Zuletzt bearbeitet von TheShadow am Sa, Feb 19, 2005 15:49, insgesamt einmal bearbeitet
 

Nemesis

BeitragSa, Feb 19, 2005 15:47
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm ich hab ne kleine hilfs c function genommen um den function auf die von getprocadress zurückgegebene function zeugen zu lassen, weil bei mir das mit nur bmax nie ging. mal schauen wie du das machst. wenn das so geht werde ich das noch ändern, mach aber sonst keinen unterschied.

--Edit--

Also das sieht nur so komplex aus weil ich es hald so gemacht habe um das auf allen platformen
gleich auszusehen lassen.
im grunde genommen verwende ich die gleiche methode wie du.
ausserdem ist es so aufgebaut das man andere "loader" einfach hinzufügen kann. ich habe mir heute mal etwas das JNI ( java native interface ) angesehen.
damit kann man auch java sachen von native code aus verwenden und ich schaue mir das gerade an in wie weit es möglich wäre da auch einen "java loader" zu machen ( natürlich etwas eingeschränkt ) und ob ich das hinkriege.

Vertex

BeitragSa, Feb 19, 2005 16:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja Nemesis gute Idee mit dem Local in der Funktion, werde es aber dennoch wie TheShadow machen, da es konfortabler ist.

Ohne zu testen habe ich mal CallDLL von BlitzClassic übernommen:

Code: [AUSKLAPPEN]
Extern "Win32"
   Function apiLoadLibrary:Int(pLibFileName:Byte Ptr) = "LoadLibraryA@4"
   Function apiGetProcAddress:Byte Ptr(iModule:Int, pProcName:Byte Ptr) = "GetProcAddress@8"
   Function apiFreeLibrary:Int(iLibModule:Int) = "FreeLibrary@4"
End Extern

Function CallDLL:Int(sDLL:String, sFunction:String, tInBank:TBank, tOutBank:TBank)
   Local iModule:Int, iAddress:Int
   Local fFunction:Int(pInBuffer:Byte Ptr, iInSize:Int, pOutBuffer:Byte Ptr, iOutSize:Int)
   Local pInBuffer:Byte Ptr, pOutBuffer:Byte Ptr, iInSize:Int, iOutSize:Int
   Local iReturn:Int
   
   iModule = apiLoadLibrary(sDLL.ToCString())
   If iModule = 0 Then Return 0
   
   iAddress = Int(apiGetprocAddress(iModule, sFunction.ToCString()))
   If iAddress = 0 Then Return 0
   
   (Int Ptr Varptr(fFunction))[0] = iAddress
   
   If tInBank Then
      pInBuffer = BankBuf(tInBank)
      iInSize = BankSize(tInBank)
   Else
      pInBuffer = Null
      iInSize = 0
   EndIf
   
   If tOutBank Then
      pOutBuffer = BankBuf(tOutBank)
      iOutSize = BankSize(tOutBank)
   Else
      pOutBuffer = Null
      iOutSize = 0
   EndIf
   
   iReturn = fFunction(pInBuffer, iInSize, pOutBuffer, iOutSize)
   
   apiFreeLibrary(iModule)
   
   Return iReturn
End Function


mfg olli
vertex.dreamfall.at | GitHub

TheShadow

Moderator

BeitragSa, Feb 19, 2005 16:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Mist leider geht meine Methode doch nicht so gut... 2tes Mal wird meine Funktion nicht gestartet...


Hier nochmal mit "Bank":



Code: [AUSKLAPPEN]

Extern "Win32"
   Function FreeLibrary:Int    (hModule:Int)
EndExtern


Local dll :Int
Local addr:Int
Local func:Int (v1:Int, v2:Int)
Local xxx:Int

dll =LoadLibraryA("dummy.dll")
addr=Int(GetProcAddress(dll,"test@8"))


Local where:Int Ptr=Int Ptr(Byte Ptr(Varptr(func)))
bank:TBank=CreateStaticBank(where,4)
PokeInt bank,0,Int(Int Ptr(addr))

Print func(3,4)
Print func(3,4)
Print func(3,4)
Print func(3,4)
Print func(3,4)
Print FreeLibrary(dll)+" <FreeLibrary"
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
  • Zuletzt bearbeitet von TheShadow am Sa, Feb 19, 2005 16:43, insgesamt einmal bearbeitet
 

Nemesis

BeitragSa, Feb 19, 2005 16:40
Antworten mit Zitat
Benutzer-Profile anzeigen
also bei mir gehts mit deinrer.
aber wie gesagt ist es praktisch genau die gleiche methode.

TheShadow

Moderator

BeitragSa, Feb 19, 2005 16:47
Antworten mit Zitat
Benutzer-Profile anzeigen
es ist immer unterschiedlich mit meiner Methode... Mal stattet es 1x, mal 3x... aber irgendwann versagt es doch... k.A. woran das nun liegt...

vielelicht weil ich die DLL paar mal neukompiliert habe... ich muss mal PC neustarten... wäre sonst sehr blöd

ich werde noch deine Lib testen...
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2

TheShadow

Moderator

BeitragSa, Feb 19, 2005 17:08
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]

#define BBDECL extern "C" __declspec(dllexport)
#define BBCALL __stdcall
#define CDECL __cdecl

BBDECL int BBCALL test(int a, int b);

BBDECL int BBCALL test(int a, int b)
{
 return a+b;
}


Das ist meine DLL mit MinGW kompilierbar

Egal nach welcher Methode ich es versuche - es klappt nie dauerhaft... Tja k.A. wie man das zum Laufen bringen kann...

hier download

http://www.blitzbase.de/codes.zip
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2

Suco-X

Betreff: ......

BeitragSa, Feb 26, 2005 1:49
Antworten mit Zitat
Benutzer-Profile anzeigen
Nur um das ganze mal zu komplettieren. Im Englischen Forum wurde die Lösung für das Problem jetzt veröffentlicht.

Version mit dem Fehler :

Code: [AUSKLAPPEN]

Local dll :Int =LoadLibraryA("dummy.dll")
Local addr:Int =Int(GetProcAddress(dll,"test@8"))
Local func:Int (v1:Int, v2:Int)

(Int Ptr(Varptr(func)))[0]=addr

Print dll +" <dummy.dll"
Print addr+" <test@8"
Print func(3,4)


Neue Version :

Code: [AUSKLAPPEN]

Local dll :Int =LoadLibraryA("dummy.dll")
Local addr:Int =Int(GetProcAddress(dll,"test@8"))
Local func:Int (v1:Int, v2:Int)"Win32"

(Int Ptr(Varptr(func)))[0]=addr

Print dll +" <dummy.dll"
Print addr+" <test@8"
Print func(3,4)


Das "Win32" ist beim Funktionspointer dazugekommen. Damit klappt die ganze Sache jetzt.
Quelle : Sweenie vom bb.com Forum.
Mfg Suco
[/code]
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB

TheShadow

Moderator

BeitragSa, Feb 26, 2005 14:12
Antworten mit Zitat
Benutzer-Profile anzeigen
jup... man muss es nur wissen... hmm

Funktioniert bei mir nun 100%ig
AMD64 3500+ | GeForce6600GT 128MB | 1GB DDR | WinXPsp2
 

#Reaper

Newsposter

BeitragMi, Aug 01, 2007 17:39
Antworten mit Zitat
Benutzer-Profile anzeigen
File not Found Sad


Hat das vielleicht noch zufällig jemand auf seiner Festplatte?
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7

Vertex

BeitragSo, Aug 05, 2007 16:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Schau dir mal Pub.OpenAL an. Da gibt es eine C-Datei die die OpenAL Library unter Windows, MacOS und Linux laden kann.
vertex.dreamfall.at | GitHub
 

#Reaper

Newsposter

BeitragMo, Aug 06, 2007 17:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, vielen Dank Smile
AMD Athlon 64 3500+, ATI AX800 Pro/TD, 2048 MB DRR 400 von Infineon, ♥RIP♥ (2005 - Juli 2015 -> sic!)
Blitz3D, BlitzMax, MaxGUI, Monkey X; Win7

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group