Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 18, 2025 19:35

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 21 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Autor Nachricht
 Betreff des Beitrags: FPC und Libs?
BeitragVerfasst: Mo Sep 19, 2005 19:54 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Hi,

kann man mit FreePascal eigentlich auch DLLs oder *.so erstellen?

Gruß,
Frase

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 19, 2005 20:09 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
Laut der Freepascal Dokumentation kann man damit Bibliotheken erstellen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 19, 2005 20:14 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Einfach library statt program an den Anfang schreiben, müßte eigentlich reichen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 19, 2005 20:16 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
stimmt. ;) Das geht. Hab's gerade selber ausprobiert.

Allerdings will es mir partout nicht gelingen, eine mit fpc erstellte DLL mit Lazarus einzubinden. Jedesmal mokiert sich das Windows. Ich hab's mal mit stdcall probiert, mal ohne. Kein Unterschied. Hat das jemand schonmal erfolgreich gemacht? Denn wenn das geht, ... *Zukunftspläne schmiede...* :twisted:

€dit: Also hier mal der Code:

Einmal meine Library:
Code:
  1. library rechnen;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   Classes
  5.   { add your units here };
  6.  
  7. function Addiere(zahl1, zahl2: integer):integer;
  8. begin
  9.   result := zahl1 + zahl2;
  10. end;
  11.  
  12. exports
  13.   addiere;
  14.  
  15. begin
  16. end.


Wenn ich die DLL im Programm einbinde:
Code:
  1. program project1;
  2. {$mode objfpc}{$H+}
  3. uses
  4.   Classes
  5.   { add your units here };
  6.  
  7. function Addiere(zahl1, zahl2: integer): integer; external 'rechnen.dll';
  8.  
  9. begin
  10.   writeln(Addiere(3,5));
  11. end.


Und wenn ich dann das Programm starte, bei dem ich die DLL eingebunden habe, kommt:
Zitat:
Die Datei PROJECT1.EXE ist
verknüpft mit dem fehlenden Export-RECHNEN.DLL:Addiere.


Hmm... Jetzt geht's irgendwie. Ich glaub', ich hab' in der DLL einfach nicht auf die Groß-/Kleinschreibung geachtet. Das kommt davon, wenn man von Pascal verwöhnt wird ;)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 19, 2005 20:44 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Ok. Nächste Frage:
Wie lade ich unter freepascal dynamisch Bibliotheken?

In Delphi unter Windows geht das ja so:
Code:
  1. type
  2.   TSummenFunktion = function(zahl1, zahl2: integer): integer; stdcall;
  3.   function addieren(zahl1, zahl2: integer): integer;
  4.  
  5. implementation
  6.  
  7. function addieren(zahl1, zahl2: integer): integer;
  8. var SummenFunktion: TSummenFunktion;
  9.     Handle: THandle;
  10. begin
  11.   Handle:=LoadLibrary(PChar(ExtractFilePath(ParamStr(0))+'rechnen.dll'));
  12.   if Handle <> 0 then begin
  13.     @SummenFunktion := GetProcAddress(Handle, 'addiere');
  14.     if @SummenFunktion <> nil then begin
  15.       result:=SummenFunktion(zahl1, zahl2);
  16.     end;
  17.     FreeLibrary(Handle);
  18.   end;
  19. end;


Aber das ist Windows-spezifischer Code. Wie mache ich das in freepascal/Lazarus?

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 19, 2005 20:46 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Unter Linux heißen die Funktionen anders. Schau mal in die Unit dglopengl.pas . Dort werden ja auch Funktionen unter Windows und Linux geladen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Sep 19, 2005 20:54 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Ich seh' den Wald vor lauter Bäumen nicht mehr. Wird mal Zeit, dass ich den abholze ;)

P.S.: Ok. Unter Windows geht's jetzt problemlos, das Einbinden von DLLs. Muss es nur noch X-Platform hinkriegen.
dglopengl.pas... Cooler Tipp, Lars. ;)

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 20, 2005 12:04 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Jo und wenn die richtige stelle findest siehst du folgendes.

Code:
  1.  
  2. function LoadLibraryEx(Name : PChar; Flags : LongInt) : Pointer; cdecl; external LibraryLib name 'dlopen';
  3. function GetProcAddressEx(Lib : Pointer; Name : PChar) : Pointer; cdecl; external LibraryLib name 'dlsym';
  4. function FreeLibraryEx(Lib : Pointer) : LongInt; cdecl; external LibraryLib name 'dlclose';
  5.  
  6. function LoadLibrary(Name : PChar) : THandle;
  7. begin
  8.  Result := THandle(LoadLibraryEx(Name, RTLD_LAZY));
  9. end;
  10.  
  11. function GetProcAddress(LibHandle : THandle; ProcName : PChar) : Pointer;
  12. begin
  13.  Result := GetProcAddressEx(Pointer(LibHandle), ProcName);
  14. end;
  15.  
  16. function FreeLibrary(LibHandle : THandle) : Boolean;
  17. begin
  18.  if LibHandle = 0 then
  19.    Result := False
  20.   else
  21.    Result := FreeLibraryEx(Pointer(LibHandle)) = 0;
  22. end;
  23.  


Dies wird übrigens auch in der OpenAL.pas finden so ziemlich 1zu1 :wink: .
Ich glaub du musst noch die classes binden und immer dran denken bei dlls und so immer case sensetive.
Meckern tut das program normalerweise nicht aber es passiert einfach nichts. In der OpenAL.pas war z.B. ein Buchstabe klein anstatt groß und schon konnte man keine Ogg Vorbis Streams mehr nutzten, weil der benötigte Befehl aus OpenAL nicht verfügbar war.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 20, 2005 20:42 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
@Tak: Dein Post enthält zwar das, worüber ich auch gestoßen bin, das allein kann es aber irgendwie nicht sein. Aber irggendwann klappt es schon noch. Momentan stellt sich nur Lazarus irgendwie quer. Angeblich habe ich den Bezeichner Handle schonmal irgendwo deklariert. ^^ Bei einem neuen Projekt... Naja ;)

Kann man in Libs eigentlich auch OOP schreiben? Wenigstens Lazarus scheint nichts dagegen zu haben. Kann man diese Dlls dann auch von anderen Sprachen (C++) nutzen oder nur von fpc?

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 20, 2005 20:55 
Offline
Ernährungsberater
Benutzeravatar

Registriert: Sa Jan 01, 2005 17:11
Beiträge: 2068
Programmiersprache: C++
In Libs kann man OOP schreiben.
Das Problem ist es nur diese zu exportieren.
Lars' Benchmark was irgendwo hier rumfliegt soll es aber gelöst haben.
Kannst es dir ja mal anschauen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 20, 2005 21:14 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
AFAIK geht es schlicht und ergreifend nicht, OOP aus DLLs zu exportieren. Das geht nur bei .NET. Lars hat es bei seinem Benchmark IMHO ohne OOP-Exporte gemacht. Will das aber nicht beschwören ;)

Bin hier gerade am Verzweifeln, weil ich es irgendwie nicht gebacken kriege, dass ich eine DLL dynamisch lade. Ohne die Cross-Platform-Version (Windows-Only) hat es prima geklappt. ^^ Außerdem kann man mit Lazarus unter Windows nicht wirklich Debuggen. Aber ok. Zu meinem Problem:

Auf euren Rat hin, hab' ich mir mal die dglopengl.pas vorgeknöpft und um ein paar Zeilen verkleinert ;)

Daraus ist diese Unit geworden (hab' die jetzt einfach mal myLib genannt):
Code:
  1. unit mylib;
  2. {$IFDEF FPC}
  3.  // Added by bero
  4.  {$MODE Delphi}
  5.  {$IFDEF CPUI386}
  6.   {$DEFINE CPU386}
  7.   {$ASMMODE INTEL}
  8.  {$ENDIF}
  9.  {$IFNDEF WIN32}
  10.   {$LINKLIB c}
  11.  {$ENDIF}
  12. {$ENDIF}
  13.  
  14. interface
  15.  
  16. uses
  17.   SysUtils{$IFDEF Win32},Windows{$ENDIF};
  18.  
  19. type
  20. {$IFDEF FPC}
  21. {$IFDEF WIN32}
  22.  // Fixed by bero
  23.   PWGLSwap = ^TWGLSwap;
  24.   {$EXTERNALSYM _WGLSWAP}
  25.   _WGLSWAP = packed record
  26.     hdc: HDC;
  27.     uiFlags: UINT;
  28.   end;
  29.   TWGLSwap = _WGLSWAP;
  30.   {$EXTERNALSYM WGLSWAP}
  31.   WGLSWAP = _WGLSWAP;
  32. {$ENDIF}
  33. {$ENDIF}
  34.  
  35. var
  36.   addiere: function(zahl1, zahl2: integer): integer; {$IFDEF Win32} stdcall; {$ELSE} cdecl; {$ENDIF}
  37.  
  38. var
  39.   LibHandle          : THandle = 0;
  40.  
  41.   procedure InitLib;
  42.   procedure DeInitLib;
  43.  
  44. implementation
  45.  
  46. {$IFNDEF Win32}
  47. // Added by bero
  48. const
  49.   RTLD_LAZY         = $001;
  50.   RTLD_NOW          = $002;
  51.   RTLD_BINDING_MASK = $003;
  52.   LibraryLib        = {$ifdef Linux}'dl'{$else}'c'{$endif};
  53.  
  54. function LoadLibraryEx(Name : PChar; Flags : LongInt) : Pointer; cdecl; external LibraryLib name 'dlopen';
  55. function GetProcAddressEx(Lib : Pointer; Name : PChar) : Pointer; cdecl; external LibraryLib name 'dlsym';
  56. function FreeLibraryEx(Lib : Pointer) : LongInt; cdecl; external LibraryLib name 'dlclose';
  57.  
  58. function LoadLibrary(Name : PChar) : THandle;
  59. begin
  60.  Result := THandle(LoadLibraryEx(Name, RTLD_LAZY));
  61. end;
  62.  
  63. function GetProcAddress(LibHandle : THandle; ProcName : PChar) : Pointer;
  64. begin
  65.  Result := GetProcAddressEx(Pointer(LibHandle), ProcName);
  66. end;
  67.  
  68. function FreeLibrary(LibHandle : THandle) : Boolean;
  69. begin
  70.  if LibHandle = 0 then
  71.    Result := False
  72.   else
  73.    Result := FreeLibraryEx(Pointer(LibHandle)) = 0;
  74. end;
  75.  
  76. function wglGetProcAddress(ProcName : PChar) : Pointer;
  77. begin
  78.  Result := GetProcAddress(LibHandle, ProcName);
  79. end;
  80. {$ENDIF}
  81.  
  82. // Thanks Mars!
  83. function glProcedure(ProcName : PChar) : Pointer;
  84. begin
  85. Result := NIL;
  86. {$IFDEF Win32}
  87. // Changed by bero
  88. if Addr(wglGetProcAddress) <> NIL then
  89.  Result := wglGetProcAddress(ProcName);
  90. if result <> NIL then
  91.  exit;
  92. {$ENDIF}
  93. Result := GetProcAddress(LibHandle, ProcName);
  94. end;
  95.  
  96. procedure InitLib;
  97. begin
  98.   LibHandle := LoadLibrary('rechnen.dll');
  99.  
  100.   if LibHandle <> 0 then
  101.     addiere := glProcedure('addiere');
  102. end;
  103.  
  104. procedure DeInitLib;
  105. begin
  106.   FreeLibrary(LibHandle);
  107. end;
  108.  
  109. initialization
  110.  
  111. finalization
  112.  
  113. end.

Hoffe, es bringt mich niemand um, weil ich jetzt ein paar Copyright-Kommentare rausgenommen hab' \";)\" Aber zwecks der Übersichtlichkeit...

Und in meinem eigentlich Programm rufe ich die function addiere so auf:
Code:
  1. InitLib;
  2. Label1.Caption := IntToStr(addiere(2,7));
  3. DeInitLib;


Meine Frage: Wo ist der Wurm? Wenn ich in der Unit myLib unten nicht hinschreibe addiere := glProcedure('addiere');, sondern z.B. addiere := glProcedure('blabla');, dann zeigt das Programm ein leicht anderes Verhalten. Mit dem korrekten Namen werden wenigstens noch merkwürdige Zahlenwerte im Label angezeigt, mit dem falschen Bezeichner dagegen nichts.

Ich weiß im Moment nicht so wirklich weiter, und ich denke mal, dass hier jemand rumgeistern könnte, der da etwas mehr Ahnung davon hat ;)

P.S.: Was haltet ihr eigentlich von der Idee, fpc als Ersatz für eine Skriptsprache zu verwenden? Also fpc kompiliert das Modul und stellt es als Lib zur Verfügung, welche dann vom Programm eingebunden wird.

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 20, 2005 21:32 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Nur eine Bitte: DeInitLib -> UnLoadLib 8)

EDIT: Das is natürlich nur was für die Ästhetic, ändert aber nichts an deinem Problem. :?

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Zuletzt geändert von Flash am Di Sep 20, 2005 22:08, insgesamt 1-mal geändert.

Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 20, 2005 21:43 
Offline
Forenkatze
Benutzeravatar

Registriert: Mi Okt 22, 2003 18:30
Beiträge: 1945
Wohnort: Närnberch
Programmiersprache: Scala, Java, C*
Flash hat geschrieben:
Nur eine Bitte: DeInitLib -> UnLoadLib 8)

:?:
Schon gut... Hat das irgendwelche tieferen Hintergründe? Vermutlich vielleicht ;)

Ja, aber was hab' ich denn jetzt bei der Lib-Einbindung vergessen? Das UnLoadLib bringt nämlich gar nix ^^

_________________
"Für kein Tier wird so viel gearbeitet wie für die Katz'."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Sep 20, 2005 21:52 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Wenn du da einen falschen Namen einträgst kann es natürlich nicht gehen, oder was meinst du?


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Sep 21, 2005 10:52 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Für mich sieht das eher aus wie ein fehler in der dll. Überprüf dochmal wie es mit FreePascal und Libary aussieht ob da dinge beachtet werden müssen. Wenn nicht einfach mal eine simple funktion mit rückgabewert Boolean und ohne parameter und testen ob das richtige ankommt. Überprüfen ob die Namen alle richtig sind auch in der dll beim exportieren. Beachte das es zufall ist wenn die Zahl ohne zuweisung 0 ist.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 21 Beiträge ]  Gehe zu Seite 1, 2  Nächste
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 3 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.011s | 14 Queries | GZIP : On ]