Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Lazarus/Free Pascal: SIGSEGV beim Aufruf einer .dll

Empfohlene Antworten

Veröffentlicht

Hallo zusammen,

ich versuche gerade mit Lazarus eine dll zu erstellen. Zunächst als Test mit einer einfachen Funktion:

function hello(name: String): String;

begin

  hello := 'Hallo ' + name;

end;

Die dll wird übersetzt und ich kann diese in meinem Programm auch einbinden. Drücke ich hier auf einen Knopf und lass mir von "hello" den Knopf-Titel ändern funktioniert das auch. Nur sobald ich ein zweites mal auf den Knopf drücke erhalte ich einen SIGSEGV. Diesen erhalte ich auch wenn ich das Programm dann einfach nur schließen will.

Ich habe im Internet leider nichts passendes gefunden bisher: Hat mir irgendjemand ein einfaches Beispiel für free pascal mit einer dll? Oder kennt jemand dieses Problem und weiß wie man es umgeht?

Kapitel 12 der fpc Doku hab ich gelesen und auch einige Beispiele im Wiki angesehen. Bloß fehlten da immer wieder mal irgendwelche Type-Definitionen. Und wenn ich das sinngemäß nachgebaut habe, habe ich halt immer obigen Fehler erhalten.

Vielen Dank,

dd

  • Autor

Das mit der Speicherzugriffsverletung ist mir schon klar. Nur weiß ich nicht wo die passiert. Dachte, dass das evtl. ein generelles Problem bei der Programmierung mit FPC ist. Deswegen auch die Frage nach dem Beispiel.

Aber um diesen konkreten Fall mit mehr Hintergrund zu füllen:

Das Programm:

unit Unit1; 


{$mode objfpc}{$H+}


interface


uses

  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,

  dynlibs;



type


  { TForm1 }


  TForm1 = class(TForm)

    Button1: TButton;

    Label1: TLabel;

    procedure Button1Click(Sender: TObject);

    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);

    procedure FormCreate(Sender: TObject);

  private

    { private declarations }

    dll: THandle;

    hello: function (name: string): string; cdecl;


  public

    { public declarations }

  end; 


var

  Form1: TForm1; 


implementation


{$R *.lfm}


{ TForm1 }


procedure TForm1.Button1Click(Sender: TObject);

begin

  Label1.Caption := hello('Du');;

end;


procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);

begin

  FreeLibrary(dll);

end;


procedure TForm1.FormCreate(Sender: TObject);

begin

  dll := LoadLibrary('project1.' + SharedSuffix);

  Pointer(hello) := GetProcedureAddress(dll, 'hello');

end;


end.

Und die dll:
library testlib;


{$mode objfpc}{$H+}


uses

  Classes

  { you can add units after this };


{$R *.res}



function hello (name: string): string; cdecl;

begin

  hello := 'Hallo ' + name;

end;


exports

  hello;


end.

Das mit der Speicherzugriffsverletung ist mir schon klar. Nur weiß ich nicht wo die passiert. Dachte, dass das evtl. ein generelles Problem bei der Programmierung mit FPC ist.

Du musst halt einmal debuggen. Prüfe einmal das Handle der Funktion auf Gültigkeit. Außerdem steht etwas über Pointer in der Doku Pointers weil THandle ist ein spezielles Handle. Weiterhin brauchst Du keine "globale" Variable auf Deine DLL, denn die DLL wird genau einmal geladen und entladen, das musst Du auch sicher stellen.

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.