Wo müssen DLLs hin ?

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

Wo müssen DLLs hin ?

Beitrag von Mathias »

Eine Frage an Windows-Freaks.

Ich habe in mein Projekt Verzeichniss eine SDL3.DLL kopiert.

Aber wen ich mein Projekt kompiliere, motzt er "Error: import library not for SDL3".
Muss die DLL irgendwo in windows/system rein ?


Oder ist mit dieser Zeile in meiner Source etwas nicht in Ordnung. Unter Linux geht alles einwandfrei.

Code: Alles auswählen

{$LinkLib 'SDL3'}
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
Levario
Beiträge: 101
Registriert: Mo 1. Sep 2014, 14:32
OS, Lazarus, FPC: Windows 10 Pro Laptop (Lazarus 3.0.0 FPC 3.2.2)
CPU-Target: 64 Bit
Wohnort: Deutschland / NRW

Re: Wo müssen DLLs hin ?

Beitrag von Levario »

Ja sie sollte zusätzlich in den C:/Windows/System32 Ordner
Du musst zusätzlich die Datei in der selben Bit Version wie dein Lazarus vorliegen haben.
Der Weg ist das Ziel... Aber bitte nicht vergessen los zu laufen :).

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

Re: Wo müssen DLLs hin ?

Beitrag von Mathias »

Ja sie sollte zusätzlich in den C:/Windows/System32 Ordner
Dies auch bei einem 64Bit Windows ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

MmVisual
Beiträge: 1466
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 3.0 FPC 3.2)
CPU-Target: 32/64Bit

Re: Wo müssen DLLs hin ?

Beitrag von MmVisual »

Es reicht vollkommen aus wenn die DLL im gleichen Ordner wie wie EXE liegt, da sucht die EXE als erstes nach der DLL.

Ich vermute mal dass die DLL "SDL3.dll" heißt und nicht nur "SDL3".

Ich würde niemals einfach so in irgend ein System Verzeichnis irgend etwas rein kopieren, damit schafft man sich nur Probleme beim Verteilen der EXE.

Abgesehen davon würde ich diese bekannte DLL dynamisch laden und nicht fest rein linken. Damit kann die EXE eine Sinnvolle Fehlermeldung erzeugen wenn die DLL nicht gefunden wurde oder in einer flaschen Version existiert.
EleLa - Elektronik Lagerverwaltung - www.elela.de

TSchnuckenbock
Beiträge: 72
Registriert: Do 20. Jul 2017, 23:47
OS, Lazarus, FPC: Win7 und Win10
CPU-Target: xxBit
Wohnort: Südheide (Schnuckenland)

Re: Wo müssen DLLs hin ?

Beitrag von TSchnuckenbock »

Wir verwenden auch eine externe dll in unserem Softwarepaket.
Wenn wir vergessen, die dll in dasselbe Verzeichnis wie die exe zu legen, kommt beim Start gleich Gemecker von wegen die BliBlaBlubb.dll fehlt.

Ich hab' mal eben nachgesehen, wie ich das damals gemacht hatte. So wie ich das sehe, hatte ich einfach nur einen Header mit den Funktionen aus der dll geschrieben. Das sieht dann z.B. mit einer Funktion "api_GetApiVersion", die in der BliBlaBlubb.dll steckt, so aus:

Code: Alles auswählen

interface

const

LIB_NAME = 'BliBlaBlubb.dll'; 

procedure api_GetApiVersion(var AMajVer: int32_t; var AMinVer: int32_t); cdecl; external LIB_NAME;
  
Ich glaube, mehr mache ich da nicht. Ich nutze die Funktion dann in meinem Programm, indem ich in der Unit diese Header-Datei in die Uses-Klausel packe und dann "api_GetApiVersion(..." aufrufe.

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

Re: Wo müssen DLLs hin ?

Beitrag von fliegermichl »

Das Problem mit statisch eingebundenen DLL's ist, dass, wenn sie nicht gefunden werden kann, das gesamte Programm nicht startet.
Deswegen lade ich die DLL's dynamisch.

Code: Alles auswählen

uses dynlibs;
const

LIB_NAME = 'BliBlaBlubb.dll'; 
type
 Tapi_GetApiVersion = procedure api_GetApiVersion(var AMajVer: int32_t; var AMinVer: int32_t); cdecl; 
 
var
 api_GetApiVersion : Tapi_ApiGetVersion;
 dllHandle : THandle;
begini
 if (FileExists(LIB_NAME)) then
 begin
  dllHandle := LoadLibrary(LIB_NAME);
  api_ApiGetVersion := GetProcAdress(dllHandle, 'api_ApiGetVersion');
 end else
  ShowMessage(LIB_NAME + ' nicht gefunden');
 end;
 
Man kann jetzt darauf reagieren, wenn die DLL oder die aufzurufende Procedure nicht gefunden wurde.

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

Re: Wo müssen DLLs hin ?

Beitrag von Mathias »

MmVisual hat geschrieben:
Mi 20. Mär 2024, 17:03
Es reicht vollkommen aus wenn die DLL im gleichen Ordner wie wie EXE liegt, da sucht die EXE als erstes nach der DLL.
Jetzt funktioniert es, ich habe festgestellt, das das Lazarus in meiner Win-VB nur 32bit ist.
Als ich die EXE aus meinem Cross-Compiler von Linux aus tat, klappte es, dort kann ich Win64 bauen.
Ich vermute mal dass die DLL "SDL3.dll" heißt und nicht nur "SDL3".
Es geht ohne dll, folgende Zeile reicht

Code: Alles auswählen

{$LinkLib 'SDL3'}
Nun habe ich das nächste Problem in einem Mini-Programm klappt es bestens.
Aber will ich es in einer Package verwenden, spuckt Lazarus folgendes aus, obwohl ich die DLL auch in meine Project-Verzeichnis kopierte.

Code: Alles auswählen

Project1.pas(27,1) Error: Import library not found for SDL3
Woran könnte die liegen ?

Jetzt habe ich gerade in Minimalst Programm gemacht.

Code: Alles auswählen

program project1;
{$LinkLib 'SDL3'}
begin
end.    
Auch da motzt er, obwohl die DLL dort auch reinkopiert wurde.
Gibt es für wine auch eine Art "ldconfig" ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Wo müssen DLLs hin ?

Beitrag von Mathias »

Ich bin noch ein kleiner Schritt weiter gekommen.
Wen ich folgendes Programm mache, wird es kompiliert.

Code: Alles auswählen

program Project1;

{$LinkLib 'SDL3'}

procedure SDL_GetVersion(ver: Pointer); cdecl; external;

begin
end.
Entferne ich aber die Zeile mit "procedure...external", kommt wir dieser Fehler.

Code: Alles auswählen

Project1.pas(8,1) Error: Import library not found for SDL3
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 830
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Wo müssen DLLs hin ?

Beitrag von PascalDragon »

Mathias hat geschrieben:
Mi 20. Mär 2024, 14:30
Aber wen ich mein Projekt kompiliere, motzt er "Error: import library not for SDL3".
Muss die DLL irgendwo in windows/system rein ?


Oder ist mit dieser Zeile in meiner Source etwas nicht in Ordnung. Unter Linux geht alles einwandfrei.

Code: Alles auswählen

{$LinkLib 'SDL3'}
{$Linklib ...} ist für statische Bibliotheken unter Windows (die unter Linux auch für dynamische Bibliotheken geht, auf Grund von Unterschieden wie Bibliotheken in ELF und PE/COFF behandelt werden). Die korrekte Verwendung für dynamische Bibliotheken (DLL unter Windows, so unter Linux) ist die „external Library name Funktion”-Syntax (und für macOS schmeißt man nur für das noch zusätzlich ein {$Linklib ...} rein).
FPC Compiler Entwickler

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

Re: Wo müssen DLLs hin ?

Beitrag von Mathias »

Ich bin einen einen Schritt weiter gekommen.
Die DLL ist in meinem Project-Verzeichniss. Ich habe eine Package für SDL3 gemacht, welche unter Linux problemlos läuft.
Wie schon gesagt, tut nur die Crosscompiler blöd.

Was ich jetzt in meinem Project gemacht habe, ich habe die package SDL3 einfernt, und dafür habe ich den Ordner wo sich die package befindet, in den Unit-Pfad des Projektes aufgenommen. Jetzt kompiliert und startet anschliessend das Programm mit wine.

Nun habe ich den Unit-Pfad wieder entfernt und die package eingebunden. Jetzt läuft es auch, bis ich den "lib" Ordner in der Package und in meinem Projekt lösche. Dann geht das Spiel wieder von vorn los.
Kompiliere ich die Package alleine, das funktionier auch.

So wie es aussieht, wen man eine DLL in einer normalen Unit einbindet, geht es,. Aber sobald es in einer Package ist, gibt es Probleme.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Acia6850
Beiträge: 15
Registriert: Mo 9. Okt 2023, 18:45
OS, Lazarus, FPC: Windows + WSL / Linux Debian Rasbian OS (L 3.0.0 FPC 3.3.2)
CPU-Target: 64Bit
Wohnort: LK Ludwigsburg

Re: Wo müssen DLLs hin ?

Beitrag von Acia6850 »

Hallo,

im Anhang ein kleines Projekt mit Win 64 C++Dll + Win64 Lazarus Dll + Win64 Exe zum Aufrufen der Funtionen.

Der C++ Code kann mit dem kostenlosen Embarcadero Dev-C++ 6.3 kompiliert werden
Die kompilierte CLib ist dabei.

In Windows sind die Dll's meist im Exe Verzeichnis der Windows Exe.
Muss aber nicht sein, man kann sie auch in ein eigenes Verzeichnis speichern.
Dann muss der Pfad und der Name der Dll beim Laden angegeben werden.

Ich lade sie immer dynamisch dann kann man den Fehler abfangen wenn sie nicht geladen werden können.

In Windows werden die Dll's in der Regel mit stdcall in der Function aufgerufen.

function xLazHelloFncA(szRsp : PAnsiChar) : PAnsiChar; stdcall; (nicht cdecl)
Dateianhänge
Lazarus_win64_LibDemo.zip
(293.1 KiB) 130-mal heruntergeladen

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

Re: Wo müssen DLLs hin ?

Beitrag von Mathias »

Ich bin immer noch am üben mir den Windoof DLLs. Daher habe ich mal eine Standard-DLL genommen, die bei jedem Windoof dabei sein müsste.

Unter Linux geht sowas ohne Probleme.

Code: Alles auswählen

$LinkLib 'GL'}
  procedure glClear(mask: longword); cdecl; external;
begin
  glClear(0);
end.
Versuche ich dasselbe mit Windoof, findet er die DLL nicht, ich habe nur folgende Zeile ersetzt.

Code: Alles auswählen

{$LinkLib 'opengl32.dll'
Lasse ich das $LinkLib weg und geben den Libname direkt an, dann wird es gefunden.

Code: Alles auswählen

  procedure glClear(mask: longword); cdecl; external 'opengl32.dll';
Bei Linux gehen beide Varianten.

Wen ich die jetzt beschrieben Varianten angucken, sind dies doch alles statischen Einbindungen, oder habe ich da etwas übersehen ?

So wie es mir bekannt ist, geht das dynamische Laden nur über LoadLibrary().

Oder habe ich das ganze immer noch nicht verstanden ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Acia6850
Beiträge: 15
Registriert: Mo 9. Okt 2023, 18:45
OS, Lazarus, FPC: Windows + WSL / Linux Debian Rasbian OS (L 3.0.0 FPC 3.3.2)
CPU-Target: 64Bit
Wohnort: LK Ludwigsburg

Re: Wo müssen DLLs hin ?

Beitrag von Acia6850 »

Hallo,

wann cdecl oder stdcall !

[Windows DLL]
Libs in Windows meist stdcall auch Windows Api.
Libs in Windows wenn c oder c++ können auch unter windows mit cdecl aufgerufen werden wenn sie vom Entwickler so definiert sind.
Ich habe immer DLLs, welche in Delphi, Lazarus und C/ C++ in Windows programmiert wurden mit stdcall deklariert.
Sie wurden auch ohne Probleme von den Anwendern in Windows so eingebunden.

[Linux]
Bei Linux habe ich eine .so gemacht und mit cdecl definiert.

[Linken in Windows]

Die Dll kann statisch gelinkt werden mit z.B procedure xyz(n : Longint); stdcall; external 'xyzLib.dll';

Vorteil einfacher Code.
Nachteil bei Fehler in Dll oder Dll nicht vorhanden. Absturz der Hauptprogrammes.

Die Dll dynamisch linken mit LoadLibrary ..

Vorteil man kann die Fehler zur Laufzeit abfangen. Dll zur Laufzeit laden und entladen.
Nachteil Code aufwändiger.

Es gibt noch eine dritte Möglichkeit mi c/c++ Libs

Wenn man den code der c/c++ Lib als Obj Datei oder als statische c/c++ Lib hat und Lazarus die dazugehörigen Runtime Libs einbinden kann , gibt es die Möglichkeit in Windows
die Funktionen der LIB statisch in die Lazarus Exe zu linken dann aber mit cdecl weil es c/c++ Funktionen sind.

z.b. {$Linklib ..\Lib\x86_64-win64\libmsvcrt.a}

Ob das in Linux funktioniert habe ich noch nicht getestet.

So kann man z.b. die SQlite.Dll als Lib in Lazarus einbinden in die Exe.

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

Re: Wo müssen DLLs hin ?

Beitrag von Mathias »

Danke für die Infos.
So wie es scheint, gibt es zwischen den OS viele kleine Unterschiede, welche einem das ganze unangenehmer machen,
Was ich gerade feststellen musste, OpenGL > 1.2 wird es echt kompliziert, die scheine da unter Windows was ganz eigenes zu haben. Unter Linux kann man statisch reinlinken, wie jede andere Lib auch.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten