Array als Parameter an DLL übergeben

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
king558
Beiträge: 25
Registriert: So 27. Aug 2023, 16:44

Array als Parameter an DLL übergeben

Beitrag von king558 »

Ich habe ein kleines Testdemo. Aber ich habe hier access violation nach dem Beenden der GUI App. Bitte um Hilfe, wie ich es korrekt umsetzen kann.

dll code

Code: Alles auswählen

library project1;


{$mode objfpc}{$H+}


uses SysUtils;


type ZNumArray = array of Integer;


procedure test1( var num : ZNumArray );
begin
  SetLength( num, 1 );
end;


exports test1;


begin
end.
gui app

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private

  public

  end;


  ZNumArray = array of Integer;
  Ptest1 = procedure ( var num : ZNumArray );


var
  Form1: TForm1;
  numArray : ZNumArray;

implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.FormCreate(Sender: TObject);
var
  dllHandle : THandle;
  test1 : Ptest1;

begin
     dllHandle := LoadLibrary( 'project1.dll' );
     if dllHandle <> 0 then
     begin
       Pointer( test1 ) := GetProcAddress( dllHandle, 'test1' );
       if @test1 <> nil then
       begin
         test1( numArray );
         numArray[ 0 ] := 100;
       end;
       test1 := nil;
       FreeLibrary( dllHandle );
     end;
end;

end.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1436
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Array als Parameter an DLL übergeben

Beitrag von fliegermichl »

In so einem Fall muß die unit sharemem sowohl bei der Anwendung als auch der dll als erste eingebunden werden.
Siehe https://www.freepascal.org/docs-html/rt ... index.html

king558
Beiträge: 25
Registriert: So 27. Aug 2023, 16:44

Re: Array als Parameter an DLL übergeben

Beitrag von king558 »

fliegermichl hat geschrieben:
Do 31. Aug 2023, 08:09
In so einem Fall muß die unit sharemem sowohl bei der Anwendung als auch der dll als erste eingebunden werden.
Siehe https://www.freepascal.org/docs-html/rt ... index.html
Danke Dir für den Hinweis, wie binde ich denn sharemem ein? Ich habe Sharemem in dll nun verwendet. Wenn ich aber in gui app auch Sharemem verwende, bekomme ich sofort nach dem Starten. "Execution stopped with exit-code -1073741515", wenn ich sharemem in gui app nicht einbinde, funktioniert die Funktion Loadlibrary nicht, erhalte den Fehlercode 119.

dll code mit Sharemem

Code: Alles auswählen

library project1;


{$mode objfpc}{$H+}


uses ShareMem, SysUtils;


type ZNumArray = array of Integer;


procedure test1( var num : ZNumArray );
begin
  SetLength( num, 1 );
end;


exports test1;


begin
end.

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Windows;

type

  { TForm1 }

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private

  public

  end;


  ZNumArray = array of Integer;
  Ptest1 = procedure ( var num : ZNumArray );


var
  Form1: TForm1;
  numArray : ZNumArray;

implementation

{$R *.lfm}

{ TForm1 }


procedure TForm1.FormCreate(Sender: TObject);
var
  dllHandle : THandle;
  test1 : Ptest1;
  errorCode : Integer;

begin
     dllHandle := LoadLibrary( 'project1.dll' );
     if dllHandle <> 0 then
     begin
       Pointer( test1 ) := GetProcAddress( dllHandle, 'test1' );
       if @test1 <> nil then
       begin
         test1( numArray );
         numArray[ 0 ] := 100;
       end;
       test1 := nil;
       FreeLibrary( dllHandle );
     end;
     errorCode := GetLastError;
end;

end.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1436
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Array als Parameter an DLL übergeben

Beitrag von fliegermichl »

sharemem muß auch in der App als ERSTE Unit eingebunden werden.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6216
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Array als Parameter an DLL übergeben

Beitrag von af0815 »

Auf was willst du hinaus ? Mit sharemem wird die Bibliothek fix an einen Memorymanger gebunden, der sehr spezifisch ist. Das ist normalerweise nicht wirklich gewünscht. Normalerweise überlegt sich, wer für den Speicher zuständig ist und wer den auch freigibt.

https://wiki.freepascal.org/shared_library
https://wiki.freepascal.org/Lazarus/FPC_Libraries
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

king558
Beiträge: 25
Registriert: So 27. Aug 2023, 16:44

Re: Array als Parameter an DLL übergeben

Beitrag von king558 »

af0815 hat geschrieben:
Do 31. Aug 2023, 10:38
Auf was willst du hinaus ? Mit sharemem wird die Bibliothek fix an einen Memorymanger gebunden, der sehr spezifisch ist. Das ist normalerweise nicht wirklich gewünscht. Normalerweise überlegt sich, wer für den Speicher zuständig ist und wer den auch freigibt.

https://wiki.freepascal.org/shared_library
https://wiki.freepascal.org/Lazarus/FPC_Libraries
Ich danke Dir für deine Hinweise, ich wollte viele Möglichkeiten kennenlernen, dann kann ich später noch die empfohlenen Variante verwenden. Daher würde ich gern auch die Möglichkeit mit Sharemem zu testen.
fliegermichl hat geschrieben:
Do 31. Aug 2023, 09:39
sharemem muß auch in der App als ERSTE Unit eingebunden werden.

Code: Alles auswählen

uses
  Sharemem, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Windows;
Das habe ich auch schon versucht, es kommt sofort diese Fehlermeldung "Execution stopped with exit-code -1073741515"

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Array als Parameter an DLL übergeben

Beitrag von theo »

king558 hat geschrieben:
Do 31. Aug 2023, 12:37

Code: Alles auswählen

uses
  Sharemem, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Windows;
Das habe ich auch schon versucht, es kommt sofort diese Fehlermeldung "Execution stopped with exit-code -1073741515"
Versuch es mal in die *.lpr zu schreiben, wo das Thread Zeug auch ist.
Menu "Projekt" -> ".lpr-Datei anzeigen" (ganz unten).

Code: Alles auswählen

program Project1;

{$mode objfpc}{$H+}

uses
  Sharemem,
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  {$IFDEF HASAMIGA}
  athreads,
  {$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, unit1
  { you can add units after this };

{$R *.res}

begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.    

king558
Beiträge: 25
Registriert: So 27. Aug 2023, 16:44

Re: Array als Parameter an DLL übergeben

Beitrag von king558 »

theo hat geschrieben:
Do 31. Aug 2023, 12:53
king558 hat geschrieben:
Do 31. Aug 2023, 12:37

Code: Alles auswählen

uses
  Sharemem, Classes, SysUtils, Forms, Controls, Graphics, Dialogs, Windows;
Das habe ich auch schon versucht, es kommt sofort diese Fehlermeldung "Execution stopped with exit-code -1073741515"
Versuch es mal in die *.lpr zu schreiben, wo das Thread Zeug auch ist.
Menu "Projekt" -> ".lpr-Datei anzeigen" (ganz unten).

Code: Alles auswählen

program Project1;

{$mode objfpc}{$H+}

uses
  Sharemem,
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  {$IFDEF HASAMIGA}
  athreads,
  {$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, unit1
  { you can add units after this };

{$R *.res}

begin
  RequireDerivedFormResource:=True;
  Application.Scaled:=True;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.    
Leider weiter kein Erfolg
Beispiel-Crash.png
Beispiel-Crash.png (49.94 KiB) 5026 mal betrachtet

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Array als Parameter an DLL übergeben

Beitrag von theo »

Ich bin auch kein Experte auf dem Gebiet.
Ich weiss nur, dass ich für die DLL/SO Schnittstellen immer möglichst einfache Typen bzw. C Kompatible Typen verwende (Auch PPChar etc.).
Was du da hast

Code: Alles auswählen

type ZNumArray = array of Integer;
Ist ein Dynamic Array mit seinen Tücken.

https://www.freepascal.org/docs-html/re ... 520003.3.1
https://forum.lazarus.freepascal.org/in ... pic=6970.0

Und af0815 hat natürlich auch recht.

Mathias
Beiträge: 6209
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Array als Parameter an DLL übergeben

Beitrag von Mathias »

Ich weiss nur, dass ich für die DLL/SO Schnittstellen immer möglichst einfache Typen bzw. C Kompatible Typen verwende (Auch PPChar etc.).
Dies würde ich auch machen, dann ist deine DLL auch kompatibel zu C und co.
Wen du es mit Pascal-Typen machst, wird ein C-Code fluchen, wen er die DLL verwenden will.
Und zu guter letzt nicht das cdecl vergessen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

king558
Beiträge: 25
Registriert: So 27. Aug 2023, 16:44

Re: Array als Parameter an DLL übergeben

Beitrag von king558 »

Mathias hat geschrieben:
Fr 1. Sep 2023, 13:30
Ich weiss nur, dass ich für die DLL/SO Schnittstellen immer möglichst einfache Typen bzw. C Kompatible Typen verwende (Auch PPChar etc.).
Dies würde ich auch machen, dann ist deine DLL auch kompatibel zu C und co.
Wen du es mit Pascal-Typen machst, wird ein C-Code fluchen, wen er die DLL verwenden will.
Und zu guter letzt nicht das cdecl vergessen.
theo hat geschrieben:
Fr 1. Sep 2023, 09:38
Ich bin auch kein Experte auf dem Gebiet.
Ich weiss nur, dass ich für die DLL/SO Schnittstellen immer möglichst einfache Typen bzw. C Kompatible Typen verwende (Auch PPChar etc.).
Was du da hast

Code: Alles auswählen

type ZNumArray = array of Integer;
Ist ein Dynamic Array mit seinen Tücken.

https://www.freepascal.org/docs-html/re ... 520003.3.1
https://forum.lazarus.freepascal.org/in ... pic=6970.0

Und af0815 hat natürlich auch recht.
Danke danke, ich habe es mittlerweise nach hartnäckig Stunden geschafft mit Sharemem zum "sauberen" Start und Beenden.

Das ist schon wirklich heftig, sobald ich freePascal unit einbinde, muss ich schon Sharemem verwenden. Das wäre z.B. JwaTlHelp3 Unit, bei Windows unit ist es kein Problem auch ohne Sharemem zu verwenden.

king558
Beiträge: 25
Registriert: So 27. Aug 2023, 16:44

Re: Array als Parameter an DLL übergeben

Beitrag von king558 »

Das Problem mit dem Absturz oder Fehler beim Starten ist es dass ich fpcmemdll.dll nicht kompiliert habe und in den Ordner neben exe Datei gelegt habe. Somit muss ich immer fpcmemdll.dll ausliefern, sofern pascal unit verwendet werden oder was. Das ist eher entmutigend. Dann wäre doch hier Dll in C++ zu schreiben.

Benutzeravatar
Jorg3000
Lazarusforum e. V.
Beiträge: 170
Registriert: So 10. Okt 2021, 10:24
OS, Lazarus, FPC: Win64
Wohnort: NRW

Re: Array als Parameter an DLL übergeben

Beitrag von Jorg3000 »

Hi!
Warum möchtest du überhaupt eine DLL erstellen, wenn sie Pascal-spezifisch sein soll?
Wenn sie nur von deinen eigenen Programmen verwendet werden soll, kann man doch leichter die betreffenden Units ins Hauptprogramm mit einkompilieren.
Es ist doch ein riesiger Vorteil von Delphi+Lazarus, dass man monolithische Anwendungen ohne Abhängigkeiten erstellen kann.
Und wenn einen die vielen Units nerven, kann man sie im Editor einfach schließen.
Ich meine, das Erstellen von DLLs macht nur Sinn, wenn man sie ohne ein Hauptprogramm weitergeben möchte.

king558
Beiträge: 25
Registriert: So 27. Aug 2023, 16:44

Re: Array als Parameter an DLL übergeben

Beitrag von king558 »

Jorg3000 hat geschrieben:
Sa 2. Sep 2023, 07:59
Hi!
Warum möchtest du überhaupt eine DLL erstellen, wenn sie Pascal-spezifisch sein soll?
Wenn sie nur von deinen eigenen Programmen verwendet werden soll, kann man doch leichter die betreffenden Units ins Hauptprogramm mit einkompilieren.
Es ist doch ein riesiger Vorteil von Delphi+Lazarus, dass man monolithische Anwendungen ohne Abhängigkeiten erstellen kann.
Und wenn einen die vielen Units nerven, kann man sie im Editor einfach schließen.
Ich meine, das Erstellen von DLLs macht nur Sinn, wenn man sie ohne ein Hauptprogramm weitergeben möchte.
Das ganze ist nur für den Lernzwecke gedacht, ich wollte so ziemlich alle Möglichkeiten der Freepascal DLL kennenlernen, um mein Wissen in Pascal zu vertiefen. Bei manchen Sachen ist schon etwas schwierig zu analysieren, warum es plötzlich zu Crash kommt, z.B. habe ich Heaprtc in dll aktiviert und unter in gui app nach Schließen, gibt es wieder unknown exception : External. obwohl dort nur leere Prozedure und Funktion drin habe.

Antworten