Userlibs in verschiedenen Programmiersprachen
Übersicht

SteffenBetreff: Userlibs in verschiedenen Programmiersprachen |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
I. Motivation:
Für viele Probleme des Programmiereralltags findet man im Internet massig C++ Beispiele. Es ist aber oft aufwendig, C++ Codes für BB umzuschreiben, da z.B. Pointer fehlen. Da wäre es doch schön, den C++ Code in BB nutzen zu können. Deshalb hat Marc Sibly in Blitz3D und BlitzPlus mit den Userlibs die Möglichkeit gegeben, *.dll-Dateien, die mit anderen Programmiersprachen geschrieben wurden, zu nutzen. In diesem Tutorial geht es darum, eigene Dlls zu schreiben, um sie in BB zu nutzen. II. Voraussetzungen: Außer einem Compiler und Kentnissen der Programmiersprache der Wahl braucht man eigentlich nichts. III. Die Programmiersprachen: III.1 Userlibs mit C++: Für MS VisualC++ gibt es auf der offiziellen Seite ein Beispiel: http://blitzbasic.com/sdkspecs/sdkspecs.php http://blitzbasic.com/sdkspecs...s_demo.zip Wer aber eher zu kostenloser Software greift, und Dev-C++(Mingw-Compiler) benutzt, wird es schwer haben, das Programm zum Laufen zu bringen. Deshalb habe ich hier beschrieben, wie man hier vorgehen kann, um Userlibs zu schreiben. 1. Als erstes muss ein neues Dll-Projekt angelegt werden: File>New>Project...>Dll 2. Es werden automatisch 2 Dateien erstellt: "dllmain.cpp" und "dll.h" (Die Dateien können aber auch anders genannt werden) 3. In die beiden Dateien werden folgende Codes geschrieben: dll.h: Code: [AUSKLAPPEN] #ifdef __cplusplus #define EXPORT extern "C" __declspec (dllexport) #else #define EXPORT __declspec (dllexport) #endif dllmain.cpp: Code: [AUSKLAPPEN] #include <windows.h> #include "dll.h" 4. Jetzt schreibt man die Funktionen, die man in BB nutzen will, einfach in die dllmain.cpp, wie man sie in ein ganz normales Programm schreiben würde: dllmain.cpp: Code: [AUSKLAPPEN] #include <windows.h> #include "dll.h" int mymagicfunction(int zahl1,int zahl2) { return (zahl1+zahl2); } 5. Der Funktionskopf wird noch um "EXPORT" und "CALLBACK" ergänzt: dllmain.cpp: Code: [AUSKLAPPEN] #include <windows.h> #include "dll.h" EXPORT int CALLBACK mymagicfunction(int zahl1,int zahl2) { return (zahl1+zahl2); } 6. Jetzt muss man noch den Funktionskopf in die dll.h kopieren: dll.h: Code: [AUSKLAPPEN] #ifdef __cplusplus #define EXPORT extern "C" __declspec (dllexport) #else #define EXPORT __declspec (dllexport) #endif EXPORT int CALLBACK mymagicfunction(int zahl1,int zahl2); 7. Beim Compilieren wird im Verzeichnis, in dem sich der Quelltext befindet, eine *.dll-Datei erstellt. 8. Die *.dll-Datei muss in eins der folgenden Verzeichnisse kopiert werden: - "Userlibs" im BB-Ordner - Systemverzeichnis - im selben Verzeichnis, wie das Programm 9. Jetzt muss man eine *.decls-Datei im "Userlibs"-Verzeichnis im BB-Ordner erstellen und mit einem Texteditor öffnen (z.b. "test.decls"). Man schreibt folgendes in die Datei: Code: [AUSKLAPPEN] .lib "test.dll" Test%( a%,b% ):"mymagicfunction" In der ersten Zeile sagt man dem Compiler, in welcher dll-Datei die Funktion ist (in diesem Fall "test.dll"). In der zweiten Zeile vor dem : steht die Funktion, wie sie in BB aufgerufen wird. Die Anzahl und Art der Parameter muss denen in C++ entsprechen. Hinter dem : steht in "" der Name der Funktion in der Dll (Bei manchen Compilern ist der Name in der Dll anders, als er im C++ Quelltext war). 10. Ab Jetzt kann unsere Funktion genau so benutzt werden, als wenn er ein BB-Befehl wäre: Code: [AUSKLAPPEN] Print Test(3,7) delay(2000) end 11. Die Dll muss dem Compilierten Programm beiliegen. Entweder muss die dll im selben Verzeichnis, wie das Programm sein, oder im Systemordner. III.2 Userlibs mit Delphi: Dieses Tutorial wurde mit [url"http://www.borland.com]Delphi 6 Personal[/url] geschrieben. Unter anderen Versionen ist vieleicht die Menüstruktur etwas anders, der Quelltext müsste aber trotzdem laufen. 1. Als erstes muss ein neues Dll-Projekt angelegt werden: File>New>Other...>Dll Wizard 2. Es wird automatisch eine *.dpr-Datei geöffnet 3. In diese Datei wird folgender Code geschrieben: Code: [AUSKLAPPEN] library test; uses SysUtils, Classes; exports begin end. Das "test" in der ersten Zeile muss man mit dem Namen der *.dpr-Datei ohne ".dpr" ersetzen (hier: test.dpr->test). 4. Jetzt schreibt man die Funktionen, die man in BB nutzen will, einfach unter den uses-Teil, wie man sie in ein ganz normales Programm schreiben würde: Code: [AUSKLAPPEN] library test; uses SysUtils, Classes; function mymagicfunction(zahl1, zahl2: Integer): Integer; begin result:=zahl1+zahl2; end; exports begin end. 5. An den Funktionskopf hängt man noch "stdcall;" an: Code: [AUSKLAPPEN] library test; uses SysUtils, Classes; function mymagicfunction(zahl1, zahl2: Integer): Integer; stdcall; begin result:=zahl1+zahl2; end; exports begin end. 6. In den "exports"-Teil muss man noch den Namen der Funktion schreiben, damit man die Funktion später in BB überhaupt aufrufen kann. Code: [AUSKLAPPEN] library test; uses SysUtils, Classes; function mymagicfunction(zahl1, zahl2: Integer): Integer; stdcall; begin result:=zahl1+zahl2; end; exports mymagicfunction; begin end. 7. Beim Compilieren wird im Verzeichnis, in dem sich der Quelltext befindet, eine *.dll-Datei erstellt. 8. Die *.dll-Datei muss in eins der folgenden Verzeichnisse kopiert werden: - "Userlibs" im BB-Ordner - Systemverzeichnis - im selben Verzeichnis, wie das Programm 9. Jetzt muss man eine *.decls-Datei im "Userlibs"-Verzeichnis im BB-Ordner erstellen und mit einem Texteditor öffnen (z.b. "test.decls"). Man schreibt folgendes in die Datei: Code: [AUSKLAPPEN] .lib "test.dll" Test%( a%,b% ):"mymagicfunction" In der ersten Zeile sagt man dem Compiler, in welcher dll-Datei die Funktion ist (in diesem Fall "test.dll"). In der zweiten Zeile vor dem : steht die Funktion, wie sie in BB aufgerufen wird. Die Anzahl und Art der Parameter muss denen in Delphi entsprechen. Hinter dem : steht in "" der Name der Funktion in der Dll. 10. Ab Jetzt kann unsere Funktion genau so benutzt werden, als wenn er ein BB-Befehl wäre: Code: [AUSKLAPPEN] Print Test(3,7) delay(2000) end 11. Die Dll muss dem Compilierten Programm beiliegen. Entweder muss die dll im selben Verzeichnis, wie das Programm sein, oder im Systemordner. III.2 Userlibs mit Purebasic: Zum Thema Userlibs mit Purebasic hat Shadowturtle auf seiner Homepage etwas bereitgestellt: http://www.shadowturtle.de/sit...n&adm= Viel Spaß beim Testen |
||
>PC: Pentium III 750MHz, ATI Rage 128 mit 32Mb, Windows Me, Blitz3D 1.87
>Laptop: Pentium M 1,4GHz, 512 Mb DDR, ATI Mobility Radeon 9000 mit 64Mb DDR, Windows XP Home, Blitz3D 1.87 |
- Zuletzt bearbeitet von Steffen am Sa, Apr 24, 2004 19:16, insgesamt 2-mal bearbeitet
![]() |
theBlade |
![]() Antworten mit Zitat ![]() |
---|---|---|
naja dazu kommen ja folgende probleme: man muss c++ bzw. delphi können. und man muss ja wissen wie man die sachen dann ansteuert die man aus BB direkt NICHT ansprechen kann. ganz so einfach isses also nicht... | ||
"Ich bin wie ich bin. Die einen kennen mich, die anderen können mich." (Dr. Konrad Adenauer)
UTFSB -> (use the fuckin "suchen"-button) User posted image <- link -.- |
![]() |
hamZtaAdministratorBetreff: hm |
![]() Antworten mit Zitat ![]() |
---|---|---|
ich finds ehrlich gesagt nicht schlecht!
das man c++ / delphi können muss is ja schließlich klar oder? und ausserdem erwähnt steffen das eh! ich finds ganz gut geschrieben, aber wie gesagt das was theBlade erwähnt hat, sollte auch noch rein! dolle sache! hamZta |
||
Blog. |
walskiEhemaliger Admin |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Sicher einer der sinnvollsten 21. Beiträge, die hier je jemand geschrieben hat!
Danke Steffen. walski |
||
buh! |
ChristianH |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Muss das nicht so sein?
Code: [AUSKLAPPEN] exports
mymagicfunction name 'test1'; Ich glaube es geht beides aber meins ist doch irgendwie deutlicher. |
||
Steffen |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@ganxta: Danke, da war wirklich ein Fehler. Ich habe den Code aus einer Test-Dll kopiert, mit der ich experimentiert habe. In dieser Dll hatte ich eine Funktion "test1". Ich habe einfach vergessen das zu ändern.
Beide Methoden hätten nicht funktioniert. Ich habe einfach den falschen Funktionsnamen verwendet, also hätte der Delphi-Compiler einen Fehler gemeldet. Deine Lösung hätte die Funktion richtig exportiert, aber unter dem Namen "test1". In den Decls wird aber auf die Funktion mymagicfunction zugegriffen. Sie ist aber in der Dll nur über den Namen test1 erreichbar, also hätte BB gemeckert. So, wie ich es verbessert habe, wird die dll richtig compiliert und die Decls stimmen auch mit der dll überein. |
||
>PC: Pentium III 750MHz, ATI Rage 128 mit 32Mb, Windows Me, Blitz3D 1.87
>Laptop: Pentium M 1,4GHz, 512 Mb DDR, ATI Mobility Radeon 9000 mit 64Mb DDR, Windows XP Home, Blitz3D 1.87 |
ChristianH |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Also:
Code: [AUSKLAPPEN] exports
mymagicfunction name 'mymagicfunction'; So stehts zumindest in meinem Delphi Buch, aber deine Methode geht glaub ich auch. |
||
![]() |
hamZtaAdministratorBetreff: hm |
![]() Antworten mit Zitat ![]() |
---|---|---|
kann man eigentlich auch strings zurück geben?
mit c++ mein ich |
||
Blog. |
Edlothiol |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ja. Die müssen in statischen Speicherbereichen gespeichert sein, sie werden dann direkt von BB kopiert. Glaube zumindest dass es so ist ![]() Code: [AUSKLAPPEN] extern "C" _declspec(dllexport) char* _stdcall gibnenstringzurueck() {
static char* s = "Dies ist ein String."; return s; } |
||
Hex² |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Auch wenn der Beitrag schon recht alt ist:
Einen dynamischen String zurückgeben: Code: [AUSKLAPPEN] EXPORT char* CALLBACK PrintLine(char *s) { return (s); } |
||
moonworx |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@Steffen,
super, vielen Dank. Ich habe mir schon etliche Haare ausgerauft den VC++-Kram zum Laufen zu bringen. Endlich die Rettung vor der Vollglatze ! |
||
Star Chasm |
Weazle25 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hex² hat Folgendes geschrieben: Auch wenn der Beitrag schon recht alt ist:
Einen dynamischen String zurückgeben: Und wie mach ich das mit Delphi? Da knobel ich schon seid Tagen rum. Hab's ja schon mit allen Datentypen (die ich brauche) hinbekommen aber wenn ich Strings zurückbekommen will bekomme ich entweder nur Pointer mit denen ich nichts anfangen kann oder Fehlermeldungen. Ich könnt kotzen. ![]() Gruss Weazle [Edit] Hab's jetzt hinbekommen. |
||
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
III.4 Userlibs mit BlitzMax:
1. http://www.svenberra.net/MakeDLL.zip herunterladen und extrahieren 2. Neue Sourcecodedatei namens "Test.bmx" anlegen: Code: [AUSKLAPPEN] SuperStrict
Framework BRL.Blitz Function DllMain:Int(hinstDLL:Byte Ptr, fdwReason:Int, lpvReserved:Byte Ptr) "win32" Select fdwReason Case 1 ' DLL_PROCESS_ATTACH Case 2 ' DLL_THREAD_ATTACH Case 3 ' DLL_THREAD_DETACH Case 0 ' DLL_PROCESS_DETACH End Select Return True End Function Function MyMagicFunction:Int(NumberA:Int, NumberB:Int) "win32" 'EXPORT Return NumberA + NumberB End Function 3. make.bat erstellen: Code: [AUSKLAPPEN] MakeDLL Test.bmx D:\BlitzMax
Pause D:\BlitzMax muss natürlich dann durch den Pfad von BlitzMax auf eurer Platte umgeändert werden wie z. B. C:\Programme\BMax o. ä. 4. make.bat starten. Von nun an, braucht man keine Pfadangaben mehr von BlitzMax zu machen, da diese in bmaxpath.txt steht ist aber nicht schlimm, wenn doch. 5. In D:\Blitz3D\userlibs die Test.dll reinkopieren und eine Test.decls anlegen: Code: [AUSKLAPPEN] .lib "Test.dll"
MyMagicFunction%(NumberA%, NumberB%) 6. Testen mit folgenden Code: Code: [AUSKLAPPEN] Print MyMagicFunction(20, 10)
WaitKey() End Wichtig bei Test.bmx: - Nicht die DllMain Funktion entfernen. Man kann sie verändern muss aber vorhanden sein und sie muss True zurückgeben(es sei denn, dass ein Fehlerhandling erfolgen soll) - Jede Funktion, die exportiert werden soll, muss mit "win32" gekennzeiichnet sein(für stdcall) und den Kommentar ' EXPORT enthalten, damit sie exportiert wird. Es lassen sich übrigens auch so DirectX Methoden ansprechen: (Siehe die deutsche Hilfe unter "SystemProperty") Code: [AUSKLAPPEN] SuperStrict
Framework PUB.DirectX Function DllMain:Int(hinstDLL:Byte Ptr, fdwReason:Int, lpvReserved:Byte Ptr) "win32" Select fdwReason Case 1 ' DLL_PROCESS_ATTACH Case 2 ' DLL_THREAD_ATTACH Case 3 ' DLL_THREAD_DETACH Case 0 ' DLL_PROCESS_DETACH End Select Return True End Function Function ChangeRenderStyle(Device:IDirect3DDevice7, Mode:Int) "win32" 'EXPORT Device.SetRenderState(D3DRS_SHADEMODE, Mode) End Function (D3DRENDERSTATE_SHADEMODE aus der Hilfe ist übrigens sogar falsch) mfg olli[/code] |
||
X0r |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Eine Frage:
Ist es denn erlaubt die BRL Sachen für dlls zu verwenden(Hab ich irgendwo im Forum gelesen)? Und wenn ich jetzt zb. Function AddStrings:String(StringA:String, StringB:String) "win32" 'EXPORT Return StringA:String+StringB:String End Function mache, wie muss das in der decls datei aussehen? Wenn ich da AddStrings%(StringA$... mache, dann kommen da nur Zahlenwerte. |
||
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nein ist es nicht.
Offiziel ist es nach wie vor Verboten mit BlitzMax irgendwelche DLLs zu machen, die man anderen in irgend einer Form zugänglich macht. Ob sich das in Zukunft ändern wird, werden wir sehen. Wers aktuell tut, riskiert mit der Aktion seine Lizenz oder gar den bb.com Account. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
X0r |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Aber was ist, wenn ich die dlls nur für meine eigenen, öffentlichen Programme verwende und in der Lizenz schreibe, dass das Nutzen von Dlls des Programmes nicht erstattet ist?
Wär das erlaubt? |
||
![]() |
Vertex |
![]() Antworten mit Zitat ![]() |
---|---|---|
Strings müssen Null terminierend sein. Also entweder über Byte Ptr oder $z arbeiten.
Ansonsten ist ja nur das BRL Zeug geschützt?! Man erzeuge folgendes Modul: Code: [AUSKLAPPEN] SuperStrict
Module Pub.Empty nutzt diesen Code: Code: [AUSKLAPPEN] SuperStrict
Framework Pub.Empty Function DllMain:Int(hinstDLL:Byte Ptr, fdwReason:Int, lpvReserved:Byte Ptr) "win32" Select fdwReason Case 1 ' DLL_PROCESS_ATTACH Case 2 ' DLL_THREAD_ATTACH Case 3 ' DLL_THREAD_DETACH Case 0 ' DLL_PROCESS_DETACH End Select Return True End Function Function MyMagicFunction:Int(NumberA:Int, NumberB:Int) "win32" 'EXPORT Return NumberA + NumberB End Function Im Assembly wird das erzeugt: Code: [AUSKLAPPEN] extrn ___bb_blitz_blitz
extrn ___bb_empty_empty und die ___bb_blitz_blitz Prozedur ist nix besonderes: Code: [AUSKLAPPEN] ___bb_blitz_blitz:
push ebp mov ebp,esp cmp dword [_89],0 je _90 mov eax,0 mov esp,ebp pop ebp ret _90: mov dword [_89],1 mov eax,0 ; ... _89: dd 0 align 4 Also damit ist das BRL Zeug m. M. nach ausgeschlossen. Und DLLs über den Flatassembler zu erstellen ist nicht verboten, da dieser OpenSource und nicht zu BRL gehört. mfg olli |
||
lettorTrepuS |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
-aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger. | ||
Czybik88 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
DLL Dateien mit VB 6.0 für BB:
Mit Vb kann man bekannterweise nur Active-X Dll erstellen. Falsch! Mit einem kleinen Trick kann man auch normale DLL Dateien erstellen, die dann wie WinAPI Funktionen aufgerufen werden können und auch in BB benutzt werden können. Ich habe mir das gerade angesehen und es funktioniert ist auch einfach zu verstehen! Tutoriallink: http://www.activevb.de/tutoria...ktdll.html |
||
Hi |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hat Jemand einen aktuellen Link zur MakeDll.zip?
Der Link oben funktioniert nicht mehr und im englischen Forum sind auch keine funktionierenden Links mehr |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group