Linkerfehler bei External Definition

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
HelmuthOL
Beiträge: 10
Registriert: Fr 22. Sep 2017, 16:26

Linkerfehler bei External Definition

Beitrag von HelmuthOL »

Die Kompilierung eines einfachen Programms funktioniert nicht, wenn eine External-Anweisung vorhanden ist, Linker-Fehler 1 beim Linken. Gleicher Code ohne External funktioniert. Fehler tritt auf mit Lazarus 1.6.4 bei 64-Bit-Version. Mit Version 1.6.0 bei 32-Bit-Version. Bei Windows-Version kein Fehler. Was mache ich falsch? Hier der simple Code:

Code: Alles auswählen

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
type
  TForm1 = class(TForm)
  private
    { private declarations }
  public
    { public declarations }
  end;
var
  Form1: TForm1;
implementation
 
Function Test(wert : Integer) : Integer; external 'MyTestLib';
 
{$R *.lfm}
end.
Zuletzt geändert von m.fuchs am Fr 22. Sep 2017, 22:45, insgesamt 1-mal geändert.
Grund: Highlighter gesetzt

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
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: Linkerfehler bei External Definition

Beitrag von af0815 »

Gibt es die dll oder so wirklich ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

HelmuthOL
Beiträge: 10
Registriert: Fr 22. Sep 2017, 16:26

Re: Linkerfehler bei External Definition

Beitrag von HelmuthOL »

Der Fehler tritt auf wenn es sie gibt und auch wenn es sie nicht gibt.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Linkerfehler bei External Definition

Beitrag von wp_xyz »

Ich weiß nicht, wo die {$R Direktive stehen muss, aber bei mir steht sie immer gleich nach "implementation", höchstens noch nach "uses", aber nie nach "ernsthaften" Deklarationen.

Ansonsten solltest du einfach ein einfaches Beispielprojekt zusammenstellen und zusammen mit der DLL hier hochladen, evtl auch mit dem Code der DLL. (Du bist neu hier: Nur Dateien, die nicht vom Compiler erzeugt werden, in ein ZIP zusammenbinden und unter "Dateianhang hochladen". Auch die DLL ins ZIP mit aufnehmen. Einfach alles, was man braucht, um das Projekt kompilieren zu können, aber auch nicht mehr. Und das Projekt so einfach wie möglich gestalten, so dass der Fehler auftritt. Niemand hat hier Lust, sich in seiner Freizeit durch ein fremdes Projekt zu wühlen).

HelmuthOL
Beiträge: 10
Registriert: Fr 22. Sep 2017, 16:26

Re: Linkerfehler bei External Definition

Beitrag von HelmuthOL »

Der fall ist ohne Aufwand zu erzeugen:
- Lazarus starten
- Datei klicken
- Neu klicken
- Anwendung wählen
- In der erzeugten Unit1 die Zeile mit der external Anweisung aus der Fehlermeldung einfügen.
Da der Fehler auftritt, egal ob die Library existiert oder nicht, erübrigt sich das hochladen eines Projekt.
Die {$R Direktive wird bei obiger Vorgehensweise automatisch eingefügt, da habe ich nix geändert.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Linkerfehler bei External Definition

Beitrag von m.fuchs »

HelmuthOL hat geschrieben:Da der Fehler auftritt, egal ob die Library existiert oder nicht, erübrigt sich das hochladen eines Projekt.


Wenn die Datei fehlt MUSS der Fehler auftreten. Wenn wir herauskriegen sollen warum er auftritt wenn sie da ist, brauchen wir die Datei.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

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

Re: Linkerfehler bei External Definition

Beitrag von Mathias »

Die Kompilierung eines einfachen Programms funktioniert nicht, wenn eine External-Anweisung vorhanden ist, Linker-Fehler 1 beim Linken.


Folgender Code wird bei mir ohne Fehler unter Linux.

Code: Alles auswählen

  function Test(wert : Integer): Integer; external 'libdl';

Aber sobald ich etwas anderes anstelle von "libdl" schreibe, also etwas das es nicht gibt, bekomme ich den gleichen Fehler wie du.

Bei Windows-Version kein Fehler.

Verstehe ich es richtig, du hast mit Linux probiert ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: Linkerfehler bei External Definition

Beitrag von wp_xyz »

Welches Betriebssystem? Unter Windows 10/64Bit kann ich den Fehler nicht reproduzieren (Laz 1.6.4/fpc3.02/64 bit, Laz 1.4.4/fpc2.6.4/32bit, Laz-trunk/fpc3.02/32bit, Laz 1.8RC4/fpc 3.04/32 bit) Was sind deine Compiler-Einstellungen? (Projekt-Optionen > Einstellungen anzeigen).

Wobei mich schon wundert, warum es bei einer nicht-existierenden DLL keinen Fehler gibt...

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Linkerfehler bei External Definition

Beitrag von Socke »

wp_xyz hat geschrieben:Wobei mich schon wundert, warum es bei einer nicht-existierenden DLL keinen Fehler gibt...

Unter Linux wird ein Minimal-Linker statisch in das Programm hineingelinkt, der die jeweilige Bibliothek dynamisch laden kann.
Windows hat sowas nicht und linkt die Bibliotheken erst zur Ausführung in das Programm hinein.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

HelmuthOL
Beiträge: 10
Registriert: Fr 22. Sep 2017, 16:26

Re: Linkerfehler bei External Definition

Beitrag von HelmuthOL »

Ich habe jetzt beim Googlen gefunden, dass die Library zur Compilierzeit vorhanden sein muss, und zwar im Verzeichnis /usr/lib oder /lib. Beides versucht, kein Erfolg. (Bei Windows braucht sie beim Compilieren nicht vorhanden sein).

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

Re: Linkerfehler bei External Definition

Beitrag von Mathias »

Ich habe jetzt beim Googlen gefunden, dass die Library zur Compilierzeit vorhanden sein muss

Dies wollte ich eigentlich sagen, da bei mir 'libdl' vorhanden war, kompilierte das Programm ohne Fehler.

Unter Linux wird ein Minimal-Linker statisch in das Programm hineingelinkt, der die jeweilige Bibliothek dynamisch laden kann.

Das merkt man gut, wen man die Package OpenGLControl in Lazarus installieren will, fehlt da eine lib welche fur OpenGL gebraucht wird, bricht Lazarus beim kompilieren ab.

Übrigens gibt es 2 Methoden um lib einzubinden, ein statische und eine dynamische.
Bei der dynamische Variante, hat man den Vorteil, das die App nicht schon beim starten abricht, wen die lib nicht vorhanden ist.
Ob die dynamische Variante auch unter Linux funktioniert, habe ich nie probiert. Man müsste dazu mal die Unit 'dynlib' genauer angucken.

Statisch:

Code: Alles auswählen

function QAPIExtOpenCard(cardnum:Longint;devnum:Longint): Longint; stdcall; external 'qlib32.dll'


Dynamisch:

Code: Alles auswählen

uses
  Windows;   // evtl. dynlibs
var
  LibHandle:THandle;
  QAPIExtOpenCard:function (cardnum:Longint;devnum:Longint): Longint; stdcall;
 
begin
  LibHandle := LoadLibrary(PChar('qlib32.dll'));
  Pointer(QAPIExtOpenCard):=GetProcAddress(LibHandle, 'QAPIExtOpenCard');
....
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Linkerfehler bei External Definition

Beitrag von kupferstecher »

HelmuthOL hat geschrieben:

Code: Alles auswählen

 
Function Test(wert : Integer) : Integer; external 'MyTestLib';
 

Stimmt der Name denn? Groß-/Kleinschreibung ist entscheidend. Evtl. wird der Name beim kompilieren der DLL auch abgeändert ("name-mangeling"). Der Kompiler selbst prüft nicht, ob die externe Funktion überhaupt vorhanden ist, erst der Linker gibt den Fehler aus, wenn er den Namen nicht zuordnen kann.

HelmuthOL
Beiträge: 10
Registriert: Fr 22. Sep 2017, 16:26

Re: Linkerfehler bei External Definition

Beitrag von HelmuthOL »

Ja, Namen richtig geschrieben. Ich habe das jetzt mit der 32-Bit Version von Lazarus probiert. Da kommen ganz andere Fehler. Ich habe es jetzt aufgegeben mit Libraries zu arbeiten. Ich gebe jetzt die .PPU und .o Files mit. Ich habe jetzt Stunden verplempert. Es geht ja auch so.

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: Linkerfehler bei External Definition

Beitrag von m.fuchs »

Tja, schade dass du dich beharrlich weigerst all Projektdateien für Lib und Programm zu zeigen. Sonst hätte man vielleicht weiterforschen können.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Linkerfehler bei External Definition

Beitrag von marcov »

Ein paar Tipps:

  • füge .dll Extension hinzu (alsp ganze DLL Namen). Auf Windows benötigen DLLs nicht da zu sein um zu linken (ohne loadlibrary), auf Linux müssen .so schon da sein, aber deshalb kann Windows solche Details nicht raten!
  • calling convention? Keine nimmt register an!
  • füge "name" Klausel zu, COFF hat ja standart ein _ Präfix.
  • deshalb sehe dich auch der DLL an mit zg PE-Explorer oder so, ist das Symbol definiert wie du es erwartest ?
  • EXE selber bittyness als DLL?

also

Code: Alles auswählen

Function Test(wert : Integer) : Integer; stdcall; external 'MyTestLib.dll' name 'Test';

Antworten