Italian community of Lazarus and Free Pascal

Programmazione => Generale => Topic aperto da: xinyiman - Febbraio 12, 2020, 02:47:05 pm

Titolo: Dynamic library primo approccio
Inserito da: xinyiman - Febbraio 12, 2020, 02:47:05 pm
Ciao ragazzi, devo ammettere con mio sommo rammarico che non ho mai usato le librerie dinamiche (.dll, .dylib, .so). Volendo fare un primo test ho scritto quanto allegato.
Sono riuscito a generare (nel mio caso la dylib) ma non riesco a capire come tirarmela dentro al programma. Qualcuno mi può aiutare?
Il primo progetto è quello che genera la dll, il progetto contenuto nella cartella client dovrebbe invece essere il programma che la usa.
So che è banale, ma non ho voglia di perdere tempo a cercare la documentazione, sicuramente qualcuno di voi sa darmi due dritte al volo per capire.
Grazie
Titolo: Re:Dynamic library primo approccio
Inserito da: Otto - Febbraio 14, 2020, 12:11:02 pm
Ciao xinyiman,
ho qualche esempio, molto semplice, funzionante in Windows OS (.dll). Non ho però esperienza diretta in OsX (.dylib), per cui mi risulta difficile testare il progetto che hai allegato.
Nel caso ti interessassero gli esempi per Windows potrei provvedere ad allegarteli in un prossimo post.

Ciao.

Otto.
 
Titolo: Re:Dynamic library primo approccio
Inserito da: xinyiman - Febbraio 14, 2020, 12:12:01 pm
Ciao otto, allega pure grazie.
Titolo: Re:Dynamic library primo approccio
Inserito da: Otto - Febbraio 14, 2020, 01:41:32 pm
Un buon punto di partenza è: https://www.tutorialspoint.com/dll/dll_delphi_example.htm

Ho allegato lo stesso esempio adattato al FPC, compilato in Lazarus e testato in Windows 10 64bit.

Sostanzialmente bisogna creare due progetti uno per la DLL (delhpdll) ed uno per il programma chiamante (Call_DLL).
In questo esempio all’interno della DLL si trovano delle semplici funzioni (min e max). All’interno del programma chiamante sono presenti due diversi metodi per richiamare e fare eseguire le funzioni che si trovano all’interno della DLL.

Spero che l’esempio riportato ti sia utile.
Titolo: Re:Dynamic library primo approccio
Inserito da: nomorelogic - Febbraio 14, 2020, 05:05:00 pm
quando dichiari
Codice: [Seleziona]
function ReverseString(Str2Rev: PChar): boolean; cdecl; external 'simpledll';

vuol dire che (es sotto windows) ci deve essere nella stessa cartella simpledll.dll

il progetto della libreria si chiama project1:
Codice: [Seleziona]
library project1;

sei sicuro che quando compili la libreria il file di output sia simpledll.dll?


Edit:
inoltre, nel file della libreria la dichiarazione è STDCALL:
Codice: [Seleziona]
function ReverseString(Str2Rev: PChar): boolean; stdcall;

mentre nel binario che la usa, la dichiari come CDECL
la dichiarazione deve essere la stessa
Titolo: Re:Dynamic library primo approccio
Inserito da: Otto - Febbraio 16, 2020, 10:46:05 am
Io uso Lazarus 2.0.6 in Windows 10 64bit, non sono riuscito ad aprire il progetto postato da xinyiman (perché probabilmente proveniente da OsX). Ho creato un nuovo progetto ed ho inserito il codice estratto dai file postati. Ho apportato piccole correzioni al codice per adattarlo e renderlo funzionante in Windows.
Ho preferito riutilizzare la funzione di xinyiman per “invertire” la stringa, apportando piccole correzioni, in modo da concentrare l’attenzione sulla chiamata della DLL (in genere utilizzo altri metodi per lavorare sulle stringhe).

DLL:
Codice: [Seleziona]
library simpledll;

{$mode objfpc}{$H+}

uses
  Classes, Sysutils;

{$R *.res}

function ReverseString(Str2Rev: PChar): boolean; stdcall;
var
   NewStr: String;
   i, sLun: integer;
Begin
  sLun:=StrLen(Str2Rev);
  if sLun>0 then Begin
     NewStr:='';
     For i:=sLun-1 downto 0 do
       NewStr := NewStr + Str2Rev[i];
     StrLCopy(Str2Rev, PChar(NewStr), sLun);
     Result := True;
  End Else
    Result := False;
End;

(*      xinyiman
function ReverseString(Str2Rev: PChar): boolean; stdcall;
var
   NewStr: String;
   NewStrPtr: PChar;
   i: integer;

Begin
     Try
        Result := False;
        NewStrPtr := @NewStr;

        For I := StrLen(Str2Rev) - 1 to 0 do
            NewStr := NewStr + Str2Rev[i];

        StrLCopy(Str2Rev, NewStrPtr, StrLen(NewStrPtr));
     Except
        Result := True;
     End;
End;
*)

exports
  ReverseString index 1;

begin
end.         

File chiamante:
Codice: [Seleziona]
unit Unit1;

{$mode objfpc}{$H+}
//{$linklib libsimpledll.dylib}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls (*, dynlibs*);

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private

  public

  end;

function ReverseString(Str2Rev: PChar): boolean; stdcall; external 'simpledll.dll';

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
var
  strA : PChar;
begin
  strA := PChar(Edit1.Text);
  if ReverseString(strA) then
    ShowMessage(strA)
  else
    ShowMessage('Errore!');
  Label1.Caption:=strA;
end;

end.       

Ciao a tutti.
Otto.

Titolo: Re:Dynamic library primo approccio
Inserito da: xinyiman - Febbraio 18, 2020, 04:19:35 pm
A chi dovesse interessare per il mondo Mac OS ecco la discussione con le soluzioni

https://forum.lazarus.freepascal.org/index.php/topic,48494.msg349746/topicseen.html#new