Userlibs in verschiedenen Programmiersprachen

Übersicht BlitzBasic FAQ und Tutorials

Neue Antwort erstellen

 

Steffen

Betreff: Userlibs in verschiedenen Programmiersprachen

BeitragDi, Feb 24, 2004 21:02
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Feb 24, 2004 21:39
Antworten mit Zitat
Benutzer-Profile anzeigen
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 -.-

hamZta

Administrator

Betreff: hm

BeitragDi, Feb 24, 2004 21:49
Antworten mit Zitat
Benutzer-Profile anzeigen
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.
 

walski

Ehemaliger Admin

BeitragDo, Feb 26, 2004 0:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Sicher einer der sinnvollsten 21. Beiträge, die hier je jemand geschrieben hat!

Danke Steffen.

walski
buh!
 

ChristianH

BeitragFr, März 05, 2004 13:48
Antworten mit Zitat
Benutzer-Profile anzeigen
Muss das nicht so sein?

Code: [AUSKLAPPEN]
exports
   mymagicfunction name 'test1';


Ich glaube es geht beides aber meins ist doch irgendwie deutlicher.
 

Steffen

BeitragFr, März 05, 2004 15:30
Antworten mit Zitat
Benutzer-Profile anzeigen
@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

BeitragFr, März 05, 2004 18:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Also:

Code: [AUSKLAPPEN]
exports
   mymagicfunction name 'mymagicfunction';


So stehts zumindest in meinem Delphi Buch, aber deine Methode geht glaub ich auch.

hamZta

Administrator

Betreff: hm

BeitragSa, März 06, 2004 10:59
Antworten mit Zitat
Benutzer-Profile anzeigen
kann man eigentlich auch strings zurück geben?
mit c++ mein ich
Blog.
 

Edlothiol

BeitragSa, März 06, 2004 12:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja. Die müssen in statischen Speicherbereichen gespeichert sein, sie werden dann direkt von BB kopiert. Glaube zumindest dass es so ist Neutral
Code: [AUSKLAPPEN]
extern "C" _declspec(dllexport) char* _stdcall gibnenstringzurueck() {
  static char* s = "Dies ist ein String.";
  return s;
}
 

Hex²

BeitragFr, Aug 05, 2005 5:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Auch wenn der Beitrag schon recht alt ist:

Einen dynamischen String zurückgeben:

Code: [AUSKLAPPEN]

EXPORT char* CALLBACK PrintLine(char *s) {
      return (s);
}
 

moonworx

BeitragMi, Okt 12, 2005 10:13
Antworten mit Zitat
Benutzer-Profile anzeigen
@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

BeitragMi, Nov 23, 2005 9:00
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Crying or Very sad


Gruss
Weazle

[Edit] Hab's jetzt hinbekommen.

Vertex

BeitragDo, Aug 17, 2006 16:33
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Aug 20, 2006 20:25
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Aug 20, 2006 20:39
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Aug 24, 2006 1:45
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Aug 24, 2006 2:09
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Aug 25, 2006 1:20
Antworten mit Zitat
Benutzer-Profile anzeigen
-aus Sicherheitsgründen gelöscht- Diese Information ist mit Ihrer Sicherheitsfreigabe leider nicht erhältlich, Bürger.
 

Czybik88

BeitragDi, Jan 23, 2007 11:58
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Okt 23, 2008 21:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Hat Jemand einen aktuellen Link zur MakeDll.zip?
Der Link oben funktioniert nicht mehr und im englischen
Forum sind auch keine funktionierenden Links mehr

Neue Antwort erstellen


Übersicht BlitzBasic FAQ und Tutorials

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group