Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   FreePascal (https://www.delphipraxis.net/74-freepascal/)
-   -   DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinden? (https://www.delphipraxis.net/148977-dll-funktionen-lazarus-fp-einbindbar-wie-einzubinden.html)

Delphi-Laie 11. Mär 2010 19:29


DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinden?
 
Hallo allerseits!

Seit geraumer Zeit suche ich mir einen Wolf im www, leider vergeblich.

Kurzum: Ist es möglich, in Lazarus / Freepascal DLL-Funktionen einzubinden, und, falls ja, wie?

Besten Dank im voraus!

Gruß Delphi-Laie

Luckie 11. Mär 2010 19:32

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Mit Sicherheit. Unter Windows mit den üblichen Windows-API Funktionen: MSDN-Library durchsuchenLoadLibrary, MSDN-Library durchsuchenGetProcAddress, MSDN-Library durchsuchenFreeLibrary.

Delphi-Laie 11. Mär 2010 19:42

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Luckie
Mit Sicherheit. Unter Windows mit den üblichen Windows-API Funktionen: MSDN-Library durchsuchenLoadLibrary, MSDN-Library durchsuchenGetProcAddress, MSDN-Library durchsuchenFreeLibrary.

Tausend Dank! Bis zum Loadlibrary kämpfte ich mich auch schon vor, das allerdings in Delphi von der Unit "windows" bereitgestellt wird. Erwartungsgemäß kennt Lazarus es nicht (jedenfalls nicht in der standardinstallierten Form).

Es gibt allerdings, wie ich gerade herausfand, in Lazarus eine Unit "Windows" (einfach probehalber manuell mit eingebunden, wird erkannt bzw. akzeptiert). Damit scheint mein Ansinnen schon deutlich günstiger auszusehen. :-D

Luckie 11. Mär 2010 19:50

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Wäre ja irgendwie etwas selten dämlich, wenn man mit FreePascal Windows Programme erstellen könnte, es aber keine Möglichkeit gäbe Windows Funktionen zu nutzen.

Delphi-Laie 11. Mär 2010 20:06

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Luckie
Wäre ja irgendwie etwas selten dämlich, wenn man mit FreePascal Windows Programme erstellen könnte, es aber keine Möglichkeit gäbe Windows Funktionen zu nutzen.

Naja, immerhin sind FreePascal/Lazarus plattformübergreifend, und so hätte es ja sein können, daß man nur Windowsprogramme erstellen kann, die Visual Controls enthalten, die auch in anderen Betriebsprogrammen bekannt sind, aber eben nicht windowsspezifische Dinge / Interna.

Edit: Mein anfänglicher Optimismus ist leider schon wieder stark gedämpft: Lazarus kennt auch mit eingebundener Unit "windows" den Befehl "GetProcAddress" nicht. Dieser ist m.E. aber nötig, um DLL-Funktionen in den DLLs zu lokalisieren.

creed steiger 11. Mär 2010 22:28

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie

Edit: Mein anfänglicher Optimismus ist leider schon wieder stark gedämpft: Lazarus kennt auch mit eingebundener Unit "windows" den Befehl "GetProcAddress" nicht. Dieser ist m.E. aber nötig, um DLL-Funktionen in den DLLs zu lokalisieren.

ist es das was du suchst?(erster Treffer)
http://www.google.de/search?hl=en&so...=Google+Search

JamesTKirk 12. Mär 2010 09:24

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Um dir noch etwas mehr auf die Sprünge zu helfen:

(Un)LoadLibrary und GetProcAddress sind plattformunabhängig in der Unit DynLibs definiert. Mit SharedSuffix hast du übrigens dann auch noch eine Konstante für die Dateierweiterung ('.dll' unter Windows und '.so' unter Linux). Die Unit Windows kannst du wieder aus deiner Uses entfernen, außer du möchtest explizit nur für Windows programmieren.

Zitat:

Zitat von Delphi-Laie
Zitat:

Zitat von Luckie
Wäre ja irgendwie etwas selten dämlich, wenn man mit FreePascal Windows Programme erstellen könnte, es aber keine Möglichkeit gäbe Windows Funktionen zu nutzen.

Naja, immerhin sind FreePascal/Lazarus plattformübergreifend, und so hätte es ja sein können, daß man nur Windowsprogramme erstellen kann, die Visual Controls enthalten, die auch in anderen Betriebsprogrammen bekannt sind, aber eben nicht windowsspezifische Dinge / Interna.

Wie meinst du das jetzt? :gruebel:

Gruß,
Sven

Delphi-Laie 12. Mär 2010 10:31

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Besten Dank, also man muß mindestens die Units windows und dynlibs einbinden, um DLL-Funktionen aufrufen bzw. benutzen zu können.

Zitat:

Zitat von creed steiger
ist es das was du suchst?(erster Treffer)
http://www.google.de/search?hl=en&so...=Google+Search

Ja, danke, aber meine Suche mit Lazarus + DLL (die Namen der nötigen Funktionen sind am Anfang ja unbekannt) führte mich zunächst hierher, und zwar zu dem Code:

Delphi-Quellcode:
procedure TForm1.KOLForm1FormCreate(Sender: PObj);
var
  DLLHandle: THandle;
  u:Integer;
  returnhandle: PHandle;
begin
  DLLHandle := Windows.LoadLibrary(SimpleLibName);
  if (DLLHandle < HINSTANCE_ERROR) then
  begin
      Label1.Caption:='DLL konnte nicht geladen werden!';
  end;
  returnhandle := GetProcAddress(DLLHandle, 'HTCSensorOpen');
end;
Dank der beiden nunmehr bekannten und eingebundenen Units bekomme ich ein analoges Beispiel auch endlich (fehlerfrei) compiliert. So, jetzt hat man ein PHandle auf die gewünschte Funktion. Wie man damit jetzt seine Wunschfunktion aufrufen kann, ist mir allerdings leider immer noch unklar. Ich bitte um Nachsicht, daß ich mal wieder ein Anfänger bin. Ich versuche, mit dieser Funktion "GetProcAdress" eine Lösung dafür im Internet zu finden.

Zitat:

Zitat von JamesTKirk
Zitat:

Zitat von Delphi-Laie
Zitat:

Zitat von Luckie
Wäre ja irgendwie etwas selten dämlich, wenn man mit FreePascal Windows Programme erstellen könnte, es aber keine Möglichkeit gäbe Windows Funktionen zu nutzen.

Naja, immerhin sind FreePascal/Lazarus plattformübergreifend, und so hätte es ja sein können, daß man nur Windowsprogramme erstellen kann, die Visual Controls enthalten, die auch in anderen Betriebsprogrammen bekannt sind, aber eben nicht windowsspezifische Dinge / Interna.

Wie meinst du das jetzt? :gruebel:

Na, ich meinte, daß es doch auch hätte sein können, daß man mit Lazarus nur solche Dinge programmieren kann, die auch plattformunabhängig oder besser plattformübergreifend vorhanden sind. Also z.B. keine Registryzugriffe. Daß es betriebsprogrammspezifische Dinge gibt, ist mir seit gestern neu, und ich sehe das natürlich positiv.

himitsu 12. Mär 2010 10:44

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie
Wie man damit jetzt seine Wunschfunktion aufrufen kann, ist mir allerdings leider immer noch unklar. Ich bitte um Nachsicht, daß ich mal wieder ein Anfänger bin. Ich versuche, mit dieser Funktion "GetProcAdress" eine Lösung dafür im Internet zu finden.

PHandle?
Einfach nur Pointer.
Oder besser noch ein Zeiger auf eine Funktion, bzw. (zumindestens in Delphi) ein Funktions-Typ. (Delphi weiß ja intern, das man damit einen Zeiger meint)

viele Beispiele siehe Hier im Forum suchenGetProcAddress


Delphi-Quellcode:
var func: function(params): result;
//type tfunc = function(params): result;
//var func: tfunc;

func := GetProcAddress...

Delphi-Laie 12. Mär 2010 13:20

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Vielen, herzlichen Dank für Eure Mühen, aber nach Stunden erfolgslosen Probierens stehe ich nunmehr total auf dem Schlauch, wie ich es Delphi schon seit Jahren nicht mehr erlebte.

Anscheinend geht es in etwa darum, die Delphi-Kapselung vieler API-Funktionen in Lazarus nachzubilden.

Ich versuche beispielhaft, die CreateToolhelp32Snapshot-Funktion zunächst erst einmal erfolreich aufzurufen, scheitere daran aber natürlich (konkret schon in der Zeile davor, in der ich die Beispielfunktion wertzuweisen beabsichtige):

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
  var
  DLLHandle,hProcessSnap: THandle;
  Beispielfunktion: function(dwFlags:Integer;th32ProcessID:Integer):THandle;//alternativ Funktionsergebnistyp:Pointer, mit dem klappt es aber auch nicht
begin
  DLLHandle := LoadLibrary(kernel32);
  if (DLLHandle < HINSTANCE_ERROR) then showmessage('DLL konnte nicht geladen werden!')
  else
    begin
    Beispielfunktion := @GetProcAddress(DLLHandle, 'CreateToolhelp32Snapshot');//klappt auch nicht, wenn ich das „@“ weglasse
    //hProcessSnap:=CreateToolHelp32SnapShot(2{TH32CS_SNAPPROCESS},0);

    FreeLibrary(kernel32)
    end
end;
An die Kryptigkeit der Fehlermeldungen habe ich mich auch längst gewöhnt, aber vor

Delphi-Quellcode:
unit1.pas(38,25) Error: Incompatible types: got "<address of function(LongInt, AnsiString):^untyped;Register>" expected "<procedure variable type of function(LongInt, LongInt):DWord;Register>"
unit1.pas(38,40) Fatal: Syntax error, ";" expected but "(" found
kapituliere ich. Um nur mal die zweite Fehlermeldung zu kommentieren: Warum darf ich GetProcAddress auf einmal nicht mehr mit Parametern aufrufen?

Ich begreife zudem nicht, was dieses ganze Rumgemache mit Loadlibrary und GetProcAddress überhaupt soll. Bisher lernte ich in Delphi die Aufrufe externer DLL-Funktionen so kennen (hat bisher, bei mir jedenfalls, immer so geklappt), Beispiel:

Delphi-Quellcode:
interface

function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;

implementation

function OpenThread; external kernel32 name 'OpenThread';

igel457 12. Mär 2010 13:47

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Ich begreife zudem nicht, was dieses ganze Rumgemache mit Loadlibrary und GetProcAddress überhaupt soll. Bisher lernte ich in Delphi die Aufrufe externer DLL-Funktionen so kennen (hat bisher, bei mir jedenfalls, immer so geklappt), Beispiel:
Delphi-Quellcode:
interface

function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;

implementation

function OpenThread; external kernel32 name 'OpenThread';

Was spricht dagegen, dass auch mit FPC so zu machen? Diese Methode nennt sich statisches Laden :gruebel:

Und folgender Code von dir zum dynamischen Laden mit LoadLibrary ist ziemlicher Unsinn (siehe Kommentare):
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
  var
  DLLHandle,hProcessSnap: THandle;
  Beispielfunktion: function(dwFlags:Integer;th32ProcessID:Integer):THandle;//alternativ Funktionsergebnistyp:Pointer, mit dem klappt es aber auch nicht
begin
  DLLHandle := LoadLibrary(kernel32);
  if (DLLHandle < HINSTANCE_ERROR) then showmessage('DLL konnte nicht geladen werden!')
  else
    begin
    Beispielfunktion := @GetProcAddress(DLLHandle, 'CreateToolhelp32Snapshot'); //Du möchtest nicht mit dem Pointer auf GetProcAddress arbeiten
    //hProcessSnap:=CreateToolHelp32SnapShot(2{TH32CS_SNAPPROCESS},0);

    FreeLibrary(kernel32) //Du willst die Funktion doch noch verwenden, also darfst du die Bibliothek nicht entladen
    end
end;

Delphi-Laie 12. Mär 2010 14:08

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Danke auch für Deine Mühe!

Zitat:

Zitat von igel457
Was spricht dagegen, dass auch mit FPC so zu machen? Diese Methode nennt sich statisches Laden :gruebel:

Na gut, statisch und dynamisch nahm ich auch schon irgendwo unterschwellig wahr. Edit: So, wie ich es von Delphi kenne (oben genannt, wohl die statische Variante), funktioniert es in Lazarus ja nicht, deshalb eben all' diese (bisher erfolglosen) Verrenkungen!

Zitat:

Zitat von igel457
Du möchtest nicht mit dem Pointer auf GetProcAddress arbeiten

Dieser Kommentar verschließt sich mir leider völlig. Wieso möchte ich nicht mit dem Pointer auf GetProcAddress arbeiten? :?:
Ich möchte einfach nur eine Funktion einer DLL benutzen. Diese muß ich anscheinend in der Weise extrahieren, daß ihre Funktionalität einer anderen Funktion übergeben wird, damit letztere (die neue, selbstdefinierte Funktion) die Funktionalität der ersteren übernimmt. Ich begreife nicht, warum das so kompliziert ist und der Lazarus/FP-Compiler sich so hartnäckig weigert. Sicher, irgendetwas stimmt nicht, doch was, weiß ich immer noch nicht.

Zitat:

Zitat von igel457
Du willst die Funktion doch noch verwenden, also darfst du die Bibliothek nicht entladen

Daß nach dem Entladen die Funktionsbenutzung nicht mehr möglich ist, ist mir durchaus klar. Ich möchte die Funktion an jener Stelle überhaupt nicht mehr benutzen. Ich hätte ja schon einen Glückshormonausstoß, wenn das erfolgreich kompilieren und - optimalerweise - die Funktion sogar erfolgreich aufgerufen würde.

Delphi-Laie 12. Mär 2010 14:28

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Die ganze Kunst scheint darin zu bestehen, den Kommandozeilenschalter

Delphi-Quellcode:
{$mode DELPHI}
zu verwenden, damit scheint es erstmal zu klappen.

Tausend Dank für die Geduld an alle! Problem (erstmal?) geklärt....

igel457 12. Mär 2010 15:21

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
"External" sollte auch ohne {$MODE DELPHI} funktionieren.

Schau dir mal die folgenden Header an, vielleicht helfen die dir:

OGG-Header (wird mit FPC mitgeliefert, statisches Laden):
http://audorra.svn.sourceforge.net/v...26&view=markup

Acinerella Header (von mir, statisches Laden):
http://audorra.svn.sourceforge.net/v...=1&view=markup

Libao Header (von mir, dynamisches Laden, AcGetProcAddress ist (fast) nur ein Synonym für GetProcAddress)
http://audorra.svn.sourceforge.net/v...36&view=markup

Delphi-Laie 12. Mär 2010 15:43

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von igel457
"External" sollte auch ohne {$MODE DELPHI} funktionieren.

Tut es aber leider nicht, wenigstens bei mir nicht. Ohne den Delphimodus bricht das Compilieren an der (beispielhafte) Zeile

Delphi-Quellcode:
function OpenThread; external kernel32 name 'OpenThread';
mit der Fehlermeldung

Delphi-Quellcode:
unit1.pas(32,20) Fatal: Syntax error, ":" expected but ";" found
ab. Auch alle Bemühungen, den Fehlermeldungen des Compilers entsprechend, diesem die Codezeile schmackhaft zu machen (und sich damit immer mehr vom ursprünglichen Delphi-Quelltext bzw. der Delphi-Syntax zu entfernen), schlugen fehl.

Danke für die Mühe, aber bei Dingen, die ich nur knapp bewältige, die eher mich regieren als umgekehrt, bin ich Dünnbrettbohrer. Bin froh, daß es jetzt überhaupt läuft...

igel457 12. Mär 2010 16:02

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Eine Funktion benötigt auch einen Rückgabewert. Und im verlinkten OGG-Header von FPC geht es auch ohne "Mode DELPHI".

JamesTKirk 12. Mär 2010 20:23

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
So... *Ärmel hochkrempelt*

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
  var
  DLLHandle,hProcessSnap: THandle;
  Beispielfunktion: function(dwFlags:Integer;th32ProcessID:Integer):THandle;//alternativ Funktionsergebnistyp:Pointer, mit dem klappt es aber auch nicht
begin
  DLLHandle := LoadLibrary(kernel32);
  if (DLLHandle < HINSTANCE_ERROR) then showmessage('DLL konnte nicht geladen werden!')
  else
    begin
    Beispielfunktion := @GetProcAddress(DLLHandle, 'CreateToolhelp32Snapshot');//klappt auch nicht, wenn ich das „@“ weglasse
    //hProcessSnap:=CreateToolHelp32SnapShot(2{TH32CS_SNAPPROCESS},0);

    FreeLibrary(kernel32)
    end
end;
Ich erkläre dir mal die Ursache im ObjFPC-Modus:
Das Problem ist hier, dass du der Variable "Beispielfunktion" einen Verweis auf die GetProcAddress-Funktion übergibst, welche sich natürlich unterscheiden. Richtig wäre hier folgendes:

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
type
  // wir benötigen einen Typ, zu dem wir casten können
  TCreateToolhelp32SnapshotProc = function(dwFlags: Integer; th32ProcessID: Integer): THandle; stdcall; // vergiss hier das stdcall nicht!
var
  DLLHandle,hProcessSnap: THandle;
  Beispielfunktion: TCreateToolhelp32SnapshotProc;
begin
  DLLHandle := LoadLibrary(kernel32);
  if (DLLHandle < HINSTANCE_ERROR) then showmessage('DLL konnte nicht geladen werden!')
  else
    begin
    // hier müssen wir jetzt auf den korrekten Typ casten
    Beispielfunktion := TCreateToolhelp32SnapshotProc(GetProcAddress(DLLHandle, 'CreateToolhelp32Snapshot'));
    //hProcessSnap:=CreateToolHelp32SnapShot(2{TH32CS_SNAPPROCESS},0);
    // aufrufen würdest du sie jetzt so:
    hProcessSnap := Beispielfunktion(2, 0);

    FreeLibrary(kernel32)
    end
end;
Ich weiß jetzt allerdings nicht aus dem Stegreif, ob der Code so dann auch unter Delphi funktioniert.

Du hast folgenden Code als Beispiel gepostet:
Delphi-Quellcode:
interface

function OpenThread(dwDesiredAccess: DWORD; bInheritHandle: BOOL; dwProcessId: DWORD): THandle; stdcall;

implementation

function OpenThread; external kernel32 name 'OpenThread';
Das Problem hier ist, das dies in meinen Augen eine Unsauberkeit des Delphi-Compilers ist. Dies sehen auch die Entwickler von Free Pascal so, weswegen sie dies nur im Delphi-kompatiblen Modus erlauben. Sowohl unter Delphi, als auch unter FPC (egal ob Modus ObjFPC oder Delphi) funktioniert folgender Code:

Delphi-Quellcode:
interface

function OpenThread(dwDesiredAccess: DWORD; bInheritedHandle: BOOl; dwProcessId: DWORD): THandle; stdcall; external kernel32 name 'OpenThread';

implementation
Hier stehen beide Angaben im Interface, was meiner Ansicht nach auch sauberer aussieht.

Und jetzt noch ein Tip am Rande: Unter Free Pascal findet sich die CreateToolHelp32SnapShot Funktion in der Unit jwatlhelp32.pas, die sich im Ordner %FPCDIR%\packages\winunits-jedi\src befindet (wobei %FPCDIR% z. B. "C:\lazarus\fpc\2.2.4" sein kann). Du brauchst den Pfad allerdings nicht mit angeben, da die Units in den Unterverzeichnissen von Packages alle in der Konfiguration von Free Pascal eingetragen sind (insofern sie für die jeweilige Plattform kompiliert wurden).
Allgemein finden sich - meines Wissens - fast alle WinAPI Funktionen in winunits-jedi. Ein Teil davon bzw die übrigen sind dann in packages/winunits-base oder rtl/win zu finden.

Gruß,
Sven

Delphi-Laie 12. Mär 2010 21:38

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Das war/ist mehr, als das kühnste Horoskop zu träumen bwz. zu prognostizieren wagte, tausend Dank(s), JamesTKirk!

So ungefähr kann ich auch alles nachvollziehen. Das wichtigste ist aber, daß ich auf die Unit „tlhelp32.pas“ bzw. auf die Verrenkungen, einzelne ihrer Funktionen zu extrahieren und woanders einzubinden, verzichten kann, wenn die mit Lazarus mitgelieferte Unit „jwatlhelp32.pas“ eine ähnliche oder sogar die gleiche Funktionalität liefert.

Bevor mir diese Informationen vorlagen, gelang es mir, die Unit „tlhelp32.pas“ mit dem o.g. Delphi-Compilerschalter fehlerfrei zu compilieren. Mit deren Funktionen wäre wohl auch ein Weiterarbeiten möglich gewesen, aber ich benutze natürlich lieber die Lazarus-Lieferpakete.

Zuguterletzt sind die in dieser Diskussion gespeicherten Kenntnisse hoffentlich auch für andere nützlich. Die 1:1-Mal-Eben-So-Portiert-Kompatibilität zwischen Delphi und Lazarus sieht in der Praxis eben doch ganz anders aus: Der Teufel steckt auch hier, wie bekanntlich (fast) überall, im Detail.

JamesTKirk 12. Mär 2010 21:51

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Schön, dass ich dir weiterhelfen konnte. :mrgreen:

Möchtest du eigentlich an dem Programm, in dem du tlhelp32 benötigst, parallel mit Delphi und Lazarus arbeiten oder nur mit Lazarus?

Bei ersterem hätte ich noch zwei verschiedene Vorschläge, mit denen du dir dein Leben erleichtern könntest.

Gruß,
Sven

Delphi-Laie 12. Mär 2010 22:20

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von JamesTKirk
Schön, dass ich dir weiterhelfen konnte. :mrgreen:

Möchtest du eigentlich an dem Programm, in dem du tlhelp32 benötigst, parallel mit Delphi und Lazarus arbeiten oder nur mit Lazarus?

Bei ersterem hätte ich noch zwei verschiedene Vorschläge, mit denen du dir dein Leben erleichtern könntest.

Gruß,
Sven

Ich möchte mein hookgesteuertes 32-Bit-Programm, das außer mir wohl kaum jemand mag (bei mir leistet es tagtäglich treue und nützliche Dienste), nach 64 Bit portieren (für mein heißgeliebtes 64-Bit-Windows-XP, das Windows finde ich richtig großartig), und dazu kommt zur Zeit leider nur Lazarus infrage. Also, die 32-Bit-Version für Delphi liegt schon vor.

Aber mit Vorschlägen mußt Du trotzdem keinesfalls geizen, die können - wem auch immer - in Situationen helfen, die man vorher gar nicht ahnt.

JamesTKirk 13. Mär 2010 12:43

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie
Ich möchte mein hookgesteuertes 32-Bit-Programm, das außer mir wohl kaum jemand mag (bei mir leistet es tagtäglich treue und nützliche Dienste), nach 64 Bit portieren (für mein heißgeliebtes 64-Bit-Windows-XP, das Windows finde ich richtig großartig), und dazu kommt zur Zeit leider nur Lazarus infrage. Also, die 32-Bit-Version für Delphi liegt schon vor.

Hmm... ich hab mir den Code in der jwatlhelp32 mal angeschaut... 64-Bit könnte hier kritisch werden, da dort (32-Bit) Assembler-Routinen verwendet werden, um die eigentlichen Methoden anzuspringen. Ich habe zwar keine Ahnung, warum die Jedis das gemacht haben, aber auf jeden Fall ist das äußerst hinderlich :wall:

Mal schauen, dass ich das mal an die FPC Entwickler melde...

Zitat:

Zitat von Delphi-Laie
Aber mit Vorschlägen mußt Du trotzdem keinesfalls geizen, die können - wem auch immer - in Situationen helfen, die man vorher gar nicht ahnt.

Diese beiden Vorschläge hätte ich:

Binde die (jwa)tlhelp32 Units folgendermaßen ein:

Delphi-Quellcode:
uses
  // andere Units
{$ifdef fpc}
  jwatlhelp32,
{$else}
  tlhelp32,
{$endif}
  // andere Units
Die andere Möglichkeit ist es die Units im Verzeichnis %FPCDIR%\packages\winunits-jedi\src in den Unit-Suchpfad von Delphi einzutragen und einfach die jwatlhelp32 Unit sowohl in Delphi, als auch in Free Pascal zu verwenden. Eventuell solltest du dann allerdings noch deinen DCU-Ausgabepfad anpassen oder du kopierst den jedi Ordner woanders hin, damit der Ordner nicht mit DCUs vollgestopft wird. So weit ich das sehe sollten die jwa* Units alle Delphi kompatibel sein.

Dadurch kannst du den Code (im Idealfall) sowohl unter Delphi, als auch unter Free Pascal verwenden.

EDIT: ok... hab nochmal genauer nachgeschaut. In den Includes von Free Pascal ist das DYNAMIC_LINK Define deaktiviert, das dafür sorgt, dass diese Assembleroutinen verwendet werden... also ist alles im grünen Bereich (das statische Linken mit "external" wird verwendet) und 64-Bit sollte kein Problem darstellen :mrgreen:

EDIT2: doppeltes Wort entfernt -.-

Gruß,
Sven

Delphi-Laie 13. Mär 2010 15:23

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Herzlichen Dank!

Mit bedingten Compilierungen bzw. Compilerschaltern dafür innerhalb des uses-Befehles hatte ich schon mit Delphi bisher nur schlechte Erfahrungen. Schon bei einem anderen Programm probierte ich nämlich erfolglos, abhängig von der Delphiversion, bestimmte units nur optional einbinden. Auch mit Lazarus will es nicht funktionieren. Alternativ jeweils den kompletten uses-Befehl in die Compilerschalter einzubinden (müßte doch eigentlich auch möglich sein?!), funktioniert in meiner DLL-Quelltextprojektdatei auch nicht - beißt sich das evtl. mit dem Delphi-Modus, den ich vorher deklarieren muß, damit es keinen Fehler gibt? Mein unter WindowsXP(64) laufendes Lazarus compilierte die im selben Verzeichnis befindliche tlhelp32.pas (diese natürlich im Delphi-Modus) erst, nachdem ich die Schalter und auch jwathelp32 aus dem uses-Befehl meiner DLL-Quelltextdatei entfernte (auskommentierte). Es handelt sich ohnehin um ein reines Windowsprogramm, warum also solche Verrenkungen, die wohl eine gewisse Plattformunabhängigkeit erreichen sollen? Ich glaube kaum, daß andere Betriebsprogramme die gleichen Hooks verwenden, ja, ich weiß nicht einmal, ob die überhaupt welche oder ersatzweise ähnliche Funktionalitäten zur Verfügung stellen.

Unter 32- und unter 64-Bit-Windows-Lazarus konnte ich immerhin die DLL-Quelltexte erfolgreich compilieren und bin damit schon weiter, als ich es zu hoffen wagte. Das 32-Bit-Compilat funktioniert in Zusammenarbeit mit dem in Delphi geschriebenen 32-Bit-Hostprogramm sogar schon (jippie!), und das immerhin zur Zufriedenheit: Die Hooks werden eingeschaltet und lösen die gewünschten Aktionen aus; es kommt von der Funktionalität her knapp an das Delphi-Compilat heran. Zwei kleine Dinge funktionieren nicht, aber die sind beide nicht(s) weltbewegend(es).

Nunmehr stehe ich vor der Aufgabe, das Hostprogramm 64 Bit mit Lazarus zu schreiben, denn das 32-Bit-Delphi-Compilat des Hostprogrammes verweigert, wie zu erwarten, die Zusammenarbeit mit der 64-Bit-DLL (es findet die DLL nicht einmal, obwohl im selben Verzeichnis liegend). Mit einem einfach Umbenennen der dpr- in eine lpr-Datei ist es natürlich beileibe nicht getan. Entweder funktioniert das dann mit einer DLL, in die units tlhelp32- und/oder einer tlhelp32 eingebunden werden, oder eben nicht. Ich lasse mich überraschen.

Dir nochmals unzählige Danks!

JamesTKirk 13. Mär 2010 15:52

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie
Alternativ jeweils den kompletten uses-Befehl in die Compilerschalter einzubinden (müßte doch eigentlich auch möglich sein?!), funktioniert in meiner DLL-Quelltextprojektdatei auch nicht - beißt sich das evtl. mit dem Delphi-Modus, den ich vorher deklarieren muß, damit es keinen Fehler gibt? Mein unter WindowsXP(64) laufendes Lazarus compilierte die im selben Verzeichnis befindliche tlhelp32.pas (diese natürlich im Delphi-Modus) erst, nachdem ich die Schalter und auch jwathelp32 aus dem uses-Befehl meiner DLL-Quelltextdatei entfernte (auskommentierte).

Würdest/könntest du mir bitte den Code zeigen, den du ausprobiert hast? Vielleicht kann ich dir helfen und für die Zukunft das Problem lösen. ;)
Zitat:

Zitat von Delphi-Laie
Es handelt sich ohnehin um ein reines Windowsprogramm, warum also solche Verrenkungen, die wohl eine gewisse Plattformunabhängigkeit erreichen sollen? Ich glaube kaum, daß andere Betriebsprogramme die gleichen Hooks verwenden, ja, ich weiß nicht einmal, ob die überhaupt welche oder ähnliche Funktionalitäten zur Verfügung stellen.

Das war jetzt auch nicht für Cross-Plattform gedacht - wobei ich Defines da äußerst gerne verwende - sondern, um die parallele Nutzung des Codes mit Delphi und FPC zu ermöglichen (wobei das ja, wie oben geschrieben, nur eine der beiden Möglichkeiten ist). Da sich Units zwischen Delphi und FPC unterscheiden können, ist es manchmal angebracht da einige solcher Verrenkungen zu betreiben, wenn man mit beiden Compilern arbeiten möchte.

Zitat:

Zitat von Delphi-Laie
Nunmehr stehe ich vor der Aufgabe, das Hostprogramm 64 Bit mit Lazarus zu schreiben, denn das 32-Bit-Delphi-Compilat des Hostprogrammes verweigert, wie zu erwarten, die Zusammenarbeit mit der 64-Bit-DLL (es findet die DLL nicht einmal, obwohl im selben Verzeichnis liegend).

Dass die DLL nicht gefunden wird, ist meiner Ansicht nach sogar eine sehr gute Lösung (von Windows - ich weiß aus dem Stegreif nicht, ob Linux da ähnlich vorgeht), da man so nicht auf die dumme Idee kommen kann eine 64-Bit DLL in einem 32-Bit Prozess zu nutzen oder umgekehrt. Dies geht nämlich spätestens bei der Annahme SizeOf(Integer)=SizeOf(Pointer) in die Hose ;)

Zitat:

Zitat von Delphi-Laie
Mit einem einfach Umbenennen der dpr- in eine lpr-Datei ist es natürlich beileibe nicht getan. Entweder funktioniert das dann mit einer DLL, in die units tlhelp32- und/oder einer tlhelp32 eingebunden werden, oder eben nicht. Ich lasse mich überraschen.

Dann noch viel Erfolg beim Umstellen und ärgere dich nicht, wenn was nicht auf Anhieb funktioniert... dafür ist ja dann das Forum da :mrgreen:

Gruß,
Sven

Delphi-Laie 13. Mär 2010 16:36

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von JamesTKirk
Würdest/könntest du mir bitte den Code zeigen, den du ausprobiert hast? Vielleicht kann ich dir helfen und für die Zukunft das Problem lösen. ;)

Da will es aber einer ganz genau wissen...also bitteschön, weder

Delphi-Quellcode:
{$mode DELPHI}{$H+}

uses Windows,
     Classes,
     
    {$ifdef fpc}
     jwatlhelp32,
     
     {$else}
     tlhelp32,
     
     {$endif}
     
     SysUtils;
noch

Delphi-Quellcode:
{$mode DELPHI}{$H+}

{$ifdef fpc}
uses Windows,
     Classes,
     jwatlhelp32,
     SysUtils;

{$else}
uses Windows,
     Classes,
     tlhelp32,
     SysUtils;

{$endif}
compilieren die tlhelp32-unit, erst, wenn ich die explizit aufrufe und damit das Compilieren erzwinge. Übrigens, {$mode DELPHI}{$H+} scheint auch ohne {$H+} zu funktioneren, also nur {$mode DELPHI} bzw. {$mode DELPHI}//{$H+}

Zitat:

Zitat von JamesTKirk
Zitat:

Zitat von Delphi-Laie
Es handelt sich ohnehin um ein reines Windowsprogramm, warum also solche Verrenkungen, die wohl eine gewisse Plattformunabhängigkeit erreichen sollen? Ich glaube kaum, daß andere Betriebsprogramme die gleichen Hooks verwenden, ja, ich weiß nicht einmal, ob die überhaupt welche oder ähnliche Funktionalitäten zur Verfügung stellen.

Das war jetzt auch nicht für Cross-Plattform gedacht - wobei ich Defines da äußerst gerne verwende - sondern, um die parallele Nutzung des Codes mit Delphi und FPC zu ermöglichen (wobei das ja, wie oben geschrieben, nur eine der beiden Möglichkeiten ist). Da sich Units zwischen Delphi und FPC unterscheiden können, ist es manchmal angebracht da einige solcher Verrenkungen zu betreiben, wenn man mit beiden Compilern arbeiten möchte.

Delphi schreibe ich allmählich ab, und Delphi 64 Bit ohnehin. Falls es noch kommen sollte, wann? Dann wird der Zeitpunkt, das noch kostendeckend, geschweige denn profitabel am Markt abzusetzen, längst vorbei sein. Freie Software war schon manches Mal schneller, und so wird es auch hier wohl sein. Aber das ist ein anderes Thema und wurde hier schon zuhauf diskutiert.

Zitat:

Zitat von JamesTKirk
Zitat:

Zitat von Delphi-Laie
Nunmehr stehe ich vor der Aufgabe, das Hostprogramm 64 Bit mit Lazarus zu schreiben, denn das 32-Bit-Delphi-Compilat des Hostprogrammes verweigert, wie zu erwarten, die Zusammenarbeit mit der 64-Bit-DLL (es findet die DLL nicht einmal, obwohl im selben Verzeichnis liegend).

Dass die DLL nicht gefunden wird, ist meiner Ansicht nach sogar eine sehr gute Lösung (von Windows - ich weiß aus dem Stegreif nicht, ob Linux da ähnlich vorgeht), da man so nicht auf die dumme Idee kommen kann eine 64-Bit DLL in einem 32-Bit Prozess zu nutzen oder umgekehrt. Dies geht nämlich spätestens bei der Annahme SizeOf(Integer)=SizeOf(Pointer) in die Hose ;)

Das ändert aber nichts daran, daß die Fehlermeldung falsch und damit irritierend ist. Die DLL im selben Verzeichnis muß gefunden werden. Vielmehr dürften Kompatibilitätsprüfungen negativ ausfallen.

Zitat:

Zitat von JamesTKirk
Zitat:

Zitat von Delphi-Laie
Mit einem einfach Umbenennen der dpr- in eine lpr-Datei ist es natürlich beileibe nicht getan. Entweder funktioniert das dann mit einer DLL, in die units tlhelp32- und/oder einer tlhelp32 eingebunden werden, oder eben nicht. Ich lasse mich überraschen.

Dann noch viel Erfolg beim Umstellen und ärgere dich nicht, wenn was nicht auf Anhieb funktioniert... dafür ist ja dann das Forum da :mrgreen:

Naja, ich kann mich durchaus noch an einen Fall erinnern, bei dem die Butter zu dick aufgetragen wurde (öffentlich versprochene Hilfe kam nicht, selbst auf Nachfrage per persönlicher Mitteilung nicht), aber das war wirklich die Ausnahme. Letztlich konnte ich mit Hilfe der Foren und auch der im Internet verstreuten sog. Tutorials alle Probleme entweder lösen oder ziemlich treffsicher (?) als unlösbar abhaken. Dafür gebührt auch diesem Forum mein Dank, und speziell natürlich an Dich!

JamesTKirk 13. Mär 2010 19:58

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Delphi-Quellcode:
{$mode DELPHI}{$H+}

uses Windows,
     Classes,
     
    {$ifdef fpc}
     jwatlhelp32,
     
     {$else}
     tlhelp32,
     
     {$endif}
     
     SysUtils;
Delphi-Quellcode:
{$mode DELPHI}{$H+}

{$ifdef fpc}
uses Windows,
     Classes,
     jwatlhelp32,
     SysUtils;

{$else}
uses Windows,
     Classes,
     tlhelp32,
     SysUtils;

{$endif}
Hmm... beide Varianten müssten zumindest mit Free Pascal funktionieren... Unter Delphi sollten sie auch komplieren, wenn du den Mode-Schalter folgendermaßen ergänzt:

Delphi-Quellcode:
{$ifdef fpc}
  {$mode delphi}{$H+}
{$endif}
Das liegt daran, dass Delphi den Modeswitch nicht kennt und im Gegensatz zu Free Pascal unbekannte Switches nicht ignoriert... Nach allem was ich weiß und verwende, sollte es dann funktionieren... Wenn nicht bleibt mir nur noch ein erstauntes "WTH?! :shock: ".

Zitat:

Zitat von Delphi-Laie
compilieren die tlhelp32-unit, erst, wenn ich die explizit aufrufe und damit das Compilieren erzwinge. Übrigens, {$mode DELPHI}{$H+} scheint auch ohne {$H+} zu funktioneren, also nur {$mode DELPHI} bzw. {$mode DELPHI}//{$H+}

Der {$H+} Switch wurde irgendwann für den Delphi-Modus als Standard übernommen, aber ich weiß nicht ab wann dies der Fall war... vor 2.4.0 aber auf jeden Fall nicht. Der Switch dient übrigens dazu, dass der Datentyp String als Alias für AnsiString gilt, statt für ShortString. Letzteres (also {$H-}) ist der Standard für alle Modi außer Delphi.

Zitat:

Zitat von Delphi-Laie
Delphi schreibe ich allmählich ab, und Delphi 64 Bit ohnehin. Falls es noch kommen sollte, wann? Dann wird der Zeitpunkt, das noch kostendeckend, geschweige denn profitabel am Markt abzusetzen, längst vorbei sein. Freie Software war schon manches Mal schneller, und so wird es auch hier wohl sein. Aber das ist ein anderes Thema und wurde hier schon zuhauf diskutiert.

Ich selbst verwende Delphi nur noch in der Arbeit und ansonsten achte ich auf Delphi-Kompatibilität nur, wenn ich Source Code veröffentliche, den auch Delphi-Benutzer verwenden könnten.

Zitat:

Zitat von Delphi-Laie
Das ändert aber nichts daran, daß die Fehlermeldung falsch und damit irritierend ist. Die DLL im selben Verzeichnis muß gefunden werden. Vielmehr dürften Kompatibilitätsprüfungen negativ ausfallen.

Du sagst also, dass beim Laden einer 64-Bit DLL in einem 32-Bit Prozess mit LoadLibrary GetLastError einen Fehlercode zurückliefert, der besagt, dass die Datei nicht gefunden wurde? Gut... das ist in der Tat irreführend und Microsoft hätte das besser implementieren können. Ich denke, dass der Loader die DLL schon findet, nur dann erkennt er, dass es sich um eine 64-Bit DLL handelt und gibt dummerweise ein "File not found" zurück... :? Ich kann es leider nicht austesten, da ich kein 64-Bit Windows zur Hand habe... mein Windows 7 ist 32-Bit und die VM mit Windows Server 2008 R2 x64 (legal über Universität erworben :mrgreen: ) muss ich erst noch aufsetzen...

Gruß,
Sven

Delphi-Laie 14. Mär 2010 16:07

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von JamesTKirk
Hmm... beide Varianten müssten zumindest mit Free Pascal funktionieren... Unter Delphi sollten sie auch komplieren, wenn du den Mode-Schalter folgendermaßen ergänzt:

Delphi-Quellcode:
{$ifdef fpc}
  {$mode delphi}{$H+}
{$endif}

Fehlt da nicht noch irgendetwas? Zwischen ifdef und endif ist nur ein Schalter gesetzt, der für Lazarus relevant ist, jedoch kein „echter“ Quelltext.

Zitat:

Zitat von JamesTKirk
Das liegt daran, dass Delphi den Modeswitch nicht kennt und im Gegensatz zu Free Pascal unbekannte Switches nicht ignoriert... Nach allem was ich weiß und verwende, sollte es dann funktionieren... Wenn nicht bleibt mir nur noch ein erstauntes "WTH?! :shock: ".

Wenn Delphi den Modeswitch nicht kennt, was soll es denn damit anfangen, wenn es das nicht ignoriert? Compilerfehler?

Eine Kompatibilität bezüglich Lazarus und Delphi reizt mich durchaus auch, aber ich verbeiße mich nicht darin.

Auf ein animiertes TrayIcon (sehr komfortabel und ergonomisch, eben lässig) werde ich aber verzichten müssen, weil das die TTrayIcon-Komponente in Lazarus nicht kennt - vielleicht wird die ja noch nachgerüstet. Ich kenne das noch von CoolTrayIcon, und erstaunlicherweise hat auch die Delphi-TTrayIcon-Komponente (oder meinetwegen auch -Klasse) diese Königsdisziplin-Funktion(alität) aufzuweisen.

Wenn ich nicht weiterkomme oder fertigbin, melde ich mich wieder, dann im ersten Fall hier, im anderen Falle im Thread, wo ich schon die 32-Bit-Variante vorstellte; Dich werde ich dann persönlich informieren.

Nochmals allerbesten Dank!

JamesTKirk 15. Mär 2010 14:55

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie
Fehlt da nicht noch irgendetwas? Zwischen ifdef und endif ist nur ein Schalter gesetzt, der für Lazarus relevant ist, jedoch kein „echter“ Quelltext.

Stell dir ifdefs einfach nur als Preprozessorkennzeichnungen vor, die vor dem Kompilieren durchgegangen werden. Alles was in einem aktiven ifdef drinsteht wird vom Compiler "bearbeitet", alles andere wird ignoriert. Und für den Compiler ist {$mode ...} ein "echter Quelltext". :zwinker:

Zitat:

Zitat von Delphi-Laie
Wenn Delphi den Modeswitch nicht kennt, was soll es denn damit anfangen, wenn es das nicht ignoriert? Compilerfehler?

Schneller Test mit Delphi 6 (bin an der Arbeit) ergibt:

Code:
Fehler: Ungültige Compileranweisung: 'mode'
Free Pascal ist da freizügiger, weil man ja nicht weiß, auf was für Ideen (bzgl. Compilerswitches) die Jungs von Borland/CodeGear/Embarcadero noch so kommen... :?

Zitat:

Zitat von Delphi-Laie
Auf ein animiertes TrayIcon (sehr komfortabel und ergonomisch, eben lässig) werde ich aber verzichten müssen, weil das die TTrayIcon-Komponente in Lazarus nicht kennt - vielleicht wird die ja noch nachgerüstet. Ich kenne das noch von CoolTrayIcon, und erstaunlicherweise hat auch die Delphi-TTrayIcon-Komponente (oder meinetwegen auch -Klasse) diese Königsdisziplin-Funktion(alität) aufzuweisen.

Ich glaube das Problem ist, dass dies nicht wirklich Cross-Plattform möglich ist... genau kann ich's dir jedoch nicht sagen, da ich mich noch nicht mit Trayicons mit Lazarus beschäftigt hab (mein Window Manager unter Linux hat nicht mal die Möglichkeit Trayicons anzuzeigen :mrgreen: ).

Gruß,
Sven

Delphi-Laie 15. Mär 2010 15:30

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Danke!

Jetzt - auf einmal - ist mir der Schalter für den FP-Compiler klar.

Ich muß auch ein wenig um Nachsicht bitten, denn ich irrte mich. Compilerschalter in der uses-Anweisung in Delphi benutzte ich doch schon erfolgreich, wie meine Recherche ergab.

Was die TrayIcons unter Lazarus anbetrifft, schaue bitte bei Interesse hier.

Ganz klar ist mir das dort zwar noch nicht, aber ich kämpfe mich voran. Warum ausgerechnet die mit Delphi gleichnamige Klasse mit Delphi inkompatibel sein soll, verschließt sich mir. Auch gelang es mir nicht, ein Objekt der (angeblich) delphikompatiblen Klasse Systrayicon zu erzeugen, weil ich nicht mal die genaue Typbezeichnung kenne (SysTrayIcon, was dort steht, funktioniert jedenfalls nicht, auch nicht als TSysTrayIcon). Benötigt man dafür mal wieder eine spezielle Unit, die dort nicht steht, analog jwatlhelp32, die mir auch unbekannt war? Und welchen Sinn soll eine nichtvisuelle TrayIcon-Klasse haben?! Egal, das sind nur rhetorische Fragen, mit TTrayIcon mache ich gerade herum, das funktioniert wenigstens. Die Delphikompatibilität behalte ich weiterhin im Auge, aber sie ist (für mich) nicht zwingend.

Delphi-Laie 21. Mär 2010 11:06

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Grüezi!

Also Du hattest recht: Die Lazarus-Unit „jwatlhelp32“ scheint in der 64-Bit-Version des Lazarus' (gibts auch eine 64-Bit-Version dieser Unit?) die Toolhelpfunktionen nicht zu unterstützen. :(

So schnell gebe ich naütürlich nicht auf. Lazarus die Unit „tlhelp32.pas“, also in Quelltextversion (die simpelste von Delphi 2.0, da sind alle für mich relevanten, entscheidenden Funktionen schon enthalten) untergeschoben, wird auch fehlerfrei compiliert und eingebunden, also die Exe wird erstellt. Wiederum sind jedoch keine Toolhelpfunktionen verfügbar.

Sooo schnell gebe ich allerdings nicht auf. Auf Dateinamensgleichheit geprüft (müßte aber stimmen, sonst gäbe es ja eine Fehlermeldung), und tatsächlich, auch unter meinem Windows XP 64 Bit heißt die angesprochene, angeforderte DLL „kernel32.dll“. Zur Sicherheit auch noch den Dependency Walker darübergejagt, doch auch die Funktionen in(nerhalb) der DLL schmücken sich inkonsequenterweise mit dem Zusatz (der Endung) „32“.

Nun tauschte ich alle DWORD-Typdeklarationen in der „tlhelp32.pas“ mit „Int64“ aus. Auch das wird fehlerfrei compiliert und eingebunden. Doch die Toolhelpfunktionen scheinen immer noch nicht zu klappen, zu funktionieren, verfügbar zu sein, was auch immer. Es gibt keine Fehlermeldung, jedoch auch keine Funktionswirkung.

Nunmehr bin ich mit meinem Latein, äh, Lazarus allmählich am Ende. :?

Weißt Du oder weiß jemand anderes noch einen Rat, Toolhelpfunktionen unter Lazarus 64 Bit verfügbar zu machen?

Immer und immer wieder dieser Scheibenkleister (Übergangsprobleme), wenn in der Computerbranche Standards wechseln.

Gruß Delphi-Laie

implementation 21. Mär 2010 11:58

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie
Sooo schnell gebe ich allerdings nicht auf. Auf Dateinamensgleichheit geprüft (müßte aber stimmen, sonst gäbe es ja eine Fehlermeldung), und tatsächlich, auch unter meinem Windows XP 64 Bit heißt die angesprochene, angeforderte DLL „kernel32.dll“. Zur Sicherheit auch noch den Dependency Walker darübergejagt, doch auch die Funktionen in(nerhalb) der DLL schmücken sich inkonsequenterweise mit dem Zusatz (der Endung) „32“.

... ist auch bei Vista und 7 so. Sehr verwirrend.
Zitat:

Zitat von Delphi-Laie
Nun tauschte ich alle DWORD-Typdeklarationen in der „tlhelp32.pas“ mit „Int64“ aus. Auch das wird fehlerfrei compiliert und eingebunden. Doch die Toolhelpfunktionen scheinen immer noch nicht zu klappen, zu funktionieren, verfügbar zu sein, was auch immer. Es gibt keine Fehlermeldung, jedoch auch keine Funktionswirkung.

1. DWord ist vorzeichenlos und Int64 vorzeichenbehaftet. Das 64bit-Pendant zu DWord ist QWord/UInt64.
2. Wie schon geschrieben wurde, sind sehr viele Assemblerblöcke drin, die eben alle für 32 bit geschrieben sind. Die müsste man alle nochmal umschreiben, damit alles vernünftig liefe.
Zitat:

Zitat von Delphi-Laie
Weißt Du oder weiß jemand anderes noch einen Rat, Toolhelpfunktionen unter Lazarus 64 Bit verfügbar zu machen?

Direkte Nutzung der Win32-API (ja, die heißt immer noch so :?, sagt zumindest das Windows SDK).
Das macht zwar die Portierung auf andere Plattformen unmöglich, aber das scheint ja so wie so keine Rolle zu spielen.

[edit]LongWord oben entfernt. Ist mir so dazwischengerutscht. Danke an JamesTKirk für den Hinweis ;D[/edit]

JamesTKirk 21. Mär 2010 12:31

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie
Also Du hattest recht: Die Lazarus-Unit „jwatlhelp32“ scheint in der 64-Bit-Version des Lazarus' (gibts auch eine 64-Bit-Version dieser Unit?) die Toolhelpfunktionen nicht zu unterstützen. :(

Inwiefern äußert sich das? Kompiliert alles? Funktioniert es nur zur Laufzeit nicht?

Zitat:

Zitat von Delphi-Laie
Sooo schnell gebe ich allerdings nicht auf. Auf Dateinamensgleichheit geprüft (müßte aber stimmen, sonst gäbe es ja eine Fehlermeldung), und tatsächlich, auch unter meinem Windows XP 64 Bit heißt die angesprochene, angeforderte DLL „kernel32.dll“. Zur Sicherheit auch noch den Dependency Walker darübergejagt, doch auch die Funktionen in(nerhalb) der DLL schmücken sich inkonsequenterweise mit dem Zusatz (der Endung) „32“.

Kannst du mal bitte eine Liste der exportierten Namen deiner kernel32.dll, die hier verwendet werden, posten? Ich habe leider noch kein 64-Bit Windows, mit dem ich rumspielen könnte.

Zitat:

Zitat von Delphi-Laie
Nun tauschte ich alle DWORD-Typdeklarationen in der „tlhelp32.pas“ mit „Int64“ aus. Auch das wird fehlerfrei compiliert und eingebunden. Doch die Toolhelpfunktionen scheinen immer noch nicht zu klappen, zu funktionieren, verfügbar zu sein, was auch immer. Es gibt keine Fehlermeldung, jedoch auch keine Funktionswirkung.

Nein, das ist meiner Meinung nach nicht das Problem. Unter Windows 64-Bit haben sich diese Strukturen nicht geändert (ich hab im MSDN nachgeschaut) und auch ein DWord ist und bleibt 32-Bit.

Zitat:

Zitat von Delphi-Laie
Weißt Du oder weiß jemand anderes noch einen Rat, Toolhelpfunktionen unter Lazarus 64 Bit verfügbar zu machen?

Funktioniert es denn, wenn du deine Anwendung als 32-Bit Anwendung kompilierst?

Zitat:

Zitat von implementation
1. DWord ist vorzeichenlos und Int64 vorzeichenbehaftet. Das 64bit-Pendant zu DWord ist QWord/LongWord/UInt64.

Unter Free Pascal sind das nur QWord und UInt64, wobei letzteres ein Alias auf QWord ist. LongWord ist ganz falsch, da dieser auch unter 64-Bit ein 32-Bit unsigned ist.

Zitat:

Zitat von implementation
2. Wie schon geschrieben wurde, sind sehr viele Assemblerblöcke drin, die eben alle für 32 bit geschrieben sind. Die müsste man alle nochmal umschreiben, damit alles vernünftig liefe.

Und direkt danach habe ich geschrieben, dass die Assemblerblöcke in der jwatlhelp32 (falls du diese meinst) alle nicht verwendet werden, da die Units mit deaktivierten DYNAMIC_LINK Define kompiliert werden und stattdessen statisches Linken (mit "external (...)") verwendet wird.

Zitat:

Zitat von implementation
Zitat:

Zitat von Delphi-Laie
Weißt Du oder weiß jemand anderes noch einen Rat, Toolhelpfunktionen unter Lazarus 64 Bit verfügbar zu machen?

Direkte Nutzung der Win32-API (ja, die heißt immer noch so :?, sagt zumindest das Windows SDK).
Das macht zwar die Portierung auf andere Plattformen unmöglich, aber das scheint ja so wie so keine Rolle zu spielen.

Ähm... was anderes macht Delphi-Laie ja gerade nicht... nur dass er schon vorgefertigte Importunits verwendet...

Gruß,
Sven

implementation 21. Mär 2010 15:54

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von JamesTKirk
Zitat:

Zitat von implementation
Zitat:

Zitat von Delphi-Laie
Weißt Du oder weiß jemand anderes noch einen Rat, Toolhelpfunktionen unter Lazarus 64 Bit verfügbar zu machen?

Direkte Nutzung der Win32-API (ja, die heißt immer noch so :?, sagt zumindest das Windows SDK).
Das macht zwar die Portierung auf andere Plattformen unmöglich, aber das scheint ja so wie so keine Rolle zu spielen.

Ähm... was anderes macht Delphi-Laie ja gerade nicht... nur dass er schon vorgefertigte Importunits verwendet...

Ähm ja, damit waren andere OS (Linux, Mac, BSD, ...) oder vollkommen unterschiedliche Architekturen gemeint. AMD64/Intel64 ist ja nur eine Erweiterung für die i386-Plattform.

JamesTKirk 21. Mär 2010 16:09

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von implementation
Zitat:

Zitat von JamesTKirk
Zitat:

Zitat von implementation
Zitat:

Zitat von Delphi-Laie
Weißt Du oder weiß jemand anderes noch einen Rat, Toolhelpfunktionen unter Lazarus 64 Bit verfügbar zu machen?

Direkte Nutzung der Win32-API (ja, die heißt immer noch so :?, sagt zumindest das Windows SDK).
Das macht zwar die Portierung auf andere Plattformen unmöglich, aber das scheint ja so wie so keine Rolle zu spielen.

Ähm... was anderes macht Delphi-Laie ja gerade nicht... nur dass er schon vorgefertigte Importunits verwendet...

Ähm ja, damit waren andere OS (Linux, Mac, BSD, ...) oder vollkommen unterschiedliche Architekturen gemeint. AMD64/Intel64 ist ja nur eine Erweiterung für die i386-Plattform.

So meinst du das... darauf bin ich gar nicht gekommen, da Delphi-Laie ja eigentlich klar gestellt hat, dass es ihm erstmal nur um Windows 64-Bit geht, vor allem weil er das Programm ja nur für den persönlichen Gebrauch zu benötigen scheint.

Gruß,
Sven

Delphi-Laie 21. Mär 2010 18:21

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Tausend Dank für Euer Engagement!

Nun, die Sache ließ mir keine Ruhe. Hier das vorläufige Ergebnis:
Ich benutze die beiden Funktionen (die erste stammt weitgehend von Luckie(s Programm „WinInfo“)) zur Ermittlung des Exe-Dateinamens eines Vordergrundfensters:

Delphi-Quellcode:
  function GetExeStringFromProcID_Processsnapshot(PID:DWORD):string;
  var hProcSnap:THandle;
  pe32:TProcessEntry32;
  begin
  hProcSnap:=CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0);
  if hProcSnap<>INVALID_HANDLE_VALUE then
    begin
    pe32.dwSize:=SizeOf(TProcessEntry32);
    if Process32First(hProcSnap,pe32) then
      begin
      if pe32.th32ProcessID=PID then
        begin
        result:=ExtractFileName(pe32.szExeFile);//ohne Extraktion wird unter ME (jedes 9.x?) der gesamte Pfad zurückgeliefert
        CloseHandle(hProcSnap);
        exit
        end;
      while Process32Next(hProcSnap,pe32)do if pe32.th32ProcessID=PID then
        begin
        result:=ExtractFileName(pe32.szExeFile);
        break
        end
      end;
    CloseHandle(hProcSnap)
    end;
  end;
und (Luckies obige Funktion diente auch hier als Vorlage)

Delphi-Quellcode:
  function GetExeStringFromProcID_Modulsnapshot(PID:DWORD):string; //stdcall;
  var hModuleSnap:THandle;
  me:TModuleEntry32;
  begin
  hModuleSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,PID);
  if hModuleSnap<>INVALID_HANDLE_VALUE then
    begin
    me.dwSize:=SizeOf(TModuleEntry32);
    if Module32First(hModuleSnap,me) then
      begin
      if uppercase(ExtractFileExt(me.szExePath))='.EXE' then
        begin
        result:=ExtractFileName(me.szExePath);
        CloseHandle(hModuleSnap);
        exit
        end;
      while Module32Next(hModuleSnap,me) do if lowercase(ExtractFileExt(me.szExePath))='.exe' then
        begin
        result:=ExtractFileName(me.szExePath);
        break
        end
      end;
    CloseHandle(hModuleSnap)
    end
  end;
Benutze ich die unit „jwatlhelp32“, scheinen sie überhaupt nicht zu funktionieren. In erster Funktion sind alle „32.th32ProcessID“ gleich 0, was natürlich falsch ist (nur der Systemprozeß hat die Nr. 0). Die „me.szExePath“ liefern verstümelte Resultate, z.B. „er.exe“ beim „explorer.exe“ oder „rus.exe“ bei „lazarus.exe“.

Unter Windows 32 Bit, mit Lazarus 32 Bit compiliert, funktioniert aber alles tadellos! Die Funktion „CreateToolHelp32SnapShot“ funktioniert allerdings auch in der 32-Bit-Version unter Windows 64 Bit, wie ich anhand meines Programmes „Prozesse“ (auch hier im Forum abgelegt) feststellen konnte.

Setze ich Lazarus (64 Bit) die unit „tlhelp32“ von Delphi 2.0 vor, scheint jetzt wenigstens der Modulschnappschuß zu funktionieren (weiß nicht, ob ich vorhin die gleiche Unit oder doch „jwatlhelp32“ benutzte, der Prozeßschnappschuß immer noch nicht. Jedenfalls sind die Ergebnisse völlig inkonsistent, so daß ich allmählich einen Fehler im Free-Pascal-Compiler vermute.

Alles Rumgemache, die Variablentypen „DWORD“ und auch „THandle“ mit „Int64“ auszutauschen, auch, einen „Int64“, auch als Konstante schon an die Funktionen zu übergeben, brachten leider auch keinen Erfolg.

Zum Glück funktioneren die Hooks unter Windows 64 Bit. Diese Hooks sind allerdings der Grund, daß ich kein 32-Bit-Compilat unter Windows 64 Bit benutzen kann.

implementation 21. Mär 2010 18:55

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von Delphi-Laie
Setze ich Lazarus (64 Bit) die unit „tlhelp32“ von Delphi 2.0 vor, scheint jetzt wenigstens der Modulschnappschuß zu funktionieren (weiß nicht, ob ich vorhin die gleiche Unit oder doch „tlhelp32“ benutzte, der Prozeßschnappschuß immer noch nicht. Jedenfalls sind die Ergebnisse völlig inkonsistent, so daß ich allmählich einen Fehler im Free-Pascal-Compiler vermute.

Was bitte hat der Compiler denn mit den ToolHelps zu tun? Worin liegt deine Vermutung? Vielleicht lässt sich der Bug (wenn ein solcher existiert) irgendwie umgehen.

Delphi-Laie 21. Mär 2010 19:40

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von implementation
Zitat:

Zitat von Delphi-Laie
Setze ich Lazarus (64 Bit) die unit „tlhelp32“ von Delphi 2.0 vor, scheint jetzt wenigstens der Modulschnappschuß zu funktionieren (weiß nicht, ob ich vorhin die gleiche Unit oder doch „tlhelp32“ benutzte, der Prozeßschnappschuß immer noch nicht. Jedenfalls sind die Ergebnisse völlig inkonsistent, so daß ich allmählich einen Fehler im Free-Pascal-Compiler vermute.

Was bitte hat der Compiler denn mit den ToolHelps zu tun? Worin liegt deine Vermutung? Vielleicht lässt sich der Bug (wenn ein solcher existiert) irgendwie umgehen.

Ich meinte natürlich:

Setze ich Lazarus (64 Bit) die unit „tlhelp32“ von Delphi 2.0 vor, scheint jetzt wenigstens der Modulschnappschuß zu funktionieren (weiß nicht, ob ich vorhin die gleiche Unit oder doch „jwatlhelp32“ benutzte), der Prozeßschnappschuß immer noch nicht. Jedenfalls sind die Ergebnisse völlig inkonsistent, so daß ich allmählich einen Fehler im Free-Pascal-Compiler vermute.

und korrigierte es weiter oben schon.

Ja, „eigentlich“ werden die externen Funktionen aus der DLL ja nur aufgerufen, also ist der Compiler nicht so recht als Schuldiger einzugrenzen. Selbst, wenn die DLL nur 32 Bit ist (die vielen „32“, im DLL-Namen und ihre immanenten Funktionen suggerieren das ja), dann müßten sie doch erst recht funktionieren.

Ich denke mir das alles nicht aus. Inskonsitente Ergebnisse sind schwer zu beschreiben, deshalb auch eine gewisse Langatmigkeit.

JamesTKirk 21. Mär 2010 20:52

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Ich sollte echt mal ein 64-Bit Windows installieren... ich melde mich dann im Laufe der Woche wieder, sobald ich das geschafft hab und du dein Problem nicht eh schon gelöst hast. :zwinker:
So wird das nämlich nichts. :mrgreen:

Gruß,
Sven

Delphi-Laie 21. Mär 2010 22:54

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Zitat:

Zitat von JamesTKirk
Ich sollte echt mal ein 64-Bit Windows installieren... ich melde mich dann im Laufe der Woche wieder, sobald ich das geschafft hab und du dein Problem nicht eh schon gelöst hast. :zwinker:
So wird das nämlich nichts. :mrgreen:

Gruß,
Sven

Wenn Du dafür die Zeit hast?! Freuen würde es mich natürlich, auch wenn ich mir keine allzugroßen Hoffnungen mehr mache. Ich will nicht voreilig eine Schuld zuweisen, aber inzwischen steht für mich ziemlich fest, daß Lazarus 64 Bit eine „Macke“ hat. Derselbe Code funktioniert nämlich in Delphis und Lazarus' (32 Bit) Compilaten tadellos.

Die Lazarus-64-Bit-Version, die ich habe, scheint nicht einmal einen integrierten Debugger zu besitzen (32-Bit-Lazarus hat einen), damit ist es natürlich gänzlich aussichtslos. Ich behalf mich mit Piepton- und Messageboxausgaben, und davon wurde ich immerhin so schlau, daß es ein Process32First gar nicht gibt (heute nachmittag gab es sogar mehrere Process32Next, doch es ergab sich als Process-ID immer nur die Null).

Ich band sogar nur die relevanten Codeteile der tlhelp32-Unit in meine beiden Programmdateien (DLL und Hostprogramm) ein, doch ein Erfolgsfortschritt will sich auch damit nicht einstellen.

Welch ein Glück, der Modulschnappschuß scheint zu funktionieren. So richtig funktioniert auch nur der eine der beiden Hooks (der Shellhook), allerdings der, den ich ohnehin bevorzuge.

Auch viele andere Abstriche mußte ich machen, aber mein Programm läuft nunmehr „gerade so“, daß es noch erträglich ist, aber in der gewünschten Grundfunktionalität: Ich öffne irgendein (Explorer- oder anderes Programm-)Fenster mit skalierbaren Dateianzeigelisten und - flupp, wie von Zauberhand - haben die Spalten automatisch die richtige Breite; etwas, was die Büroklammerntanzprogrammierer bis heute nicht hinbekamen (korrekterweise wohl eher: nicht programmieren durften, denn ich bediene mich auch nur der mitgelieferten Bordmittel). Ich werde an dem 64-Bit-Programm deshalb auch keine Zeit mehr ver(sch)wenden, es sei denn, ich bekomme noch irgendwelche interessanten Anregungen oder eine neue Lazarus-64-Bit-Version.

Es kann aber durchaus sein, daß ich mein Programm „Prozesse“ nach Lazarus und dann natürlich auch zu 64 Bit migrieren werde - auch wenn das beileibe nicht so einfach ist, wie von jemandem in diesem Forum behauptet - den Beweis, daß mein o.a. Vermutung richtig ist, hätte ich nämlich selbst gern.

Spannend und zukunftsträchtig („zukunftssicher“) sind 64 Bit allemal, nicht nur die aus Redmond! :wink:

Delphi-Laie 22. Mär 2010 11:15

Fehler in Lazarus 64 Bit für Windows?!
 
Liste der Anhänge anzeigen (Anzahl: 1)
Mein gestriger Verdacht hat sich erhärtet, ja eigentlich schon bestätigt.

Um das festzustellen, bediente ich mich auf die Schnelle Luckies Programmes „WinInfo“, daß ich mal eben so nach Lazarus portierte (wenn alle Portierungen so reibungslos wären!). Lediglich die beiden Vergleiche „= true“ in der Funktion „GetExeStringFromProcID“ entfernte ich, und dieses Entfernen hat seine Richtigkeit, wie er mir schon vor Jahren bestätigte (ich zettelte dazu sogar mal eine Diskussion an, die sehr lebhaft wurde).

Kurzum, erwartungsgemäß bleibt das Feld „Anwendung“, das sich dieser o.g. Funktion bedient (die wiederum kernel32-Funktionen benutzt) und den Exe-Dateinamen ausspucken soll, in der 64-Bit-Version leer. Das 32-Bit-Compilat funktioniert jedoch unter beiden Umgebungen.

Merkwürdigerweise bekam ich die das Programm mit eingebundener Unit „jwatlhelp32“ weder unter Lazarus 32 noch 64 Bit compiliert - die IDEs fanden sie wohl nicht. Nur mit tlhelp32 ließ es sich kompilieren.

Ich lege zum schnellen Ausprobieren (wen es interessiert) den Quelltext (der ja ursprünglich von Luckie stammt, das sei hier noch einmal wiederholt) und die beiden Compilate als Komprimat hier ab.

Also, trotz Einbindung externer DLL-Funktionen, für die der Compiler auf den ersten Blick ja nicht verantwortlich ist, stimmt irgendetwas mit dem 64-Bit-Lazarus nicht.

Viele Grüße

Delphi-Laie

Unit jwatlhelp32 wird doch gefunden, war ein Schreibfehler (verdammt schmales kleines L!) meinerseite im Quelltext. Funktioniert aber, wie schon hier in dieser Diskussion vermutet, auch nicht.

implementation 22. Mär 2010 15:01

Re: DLL-Funktionen in Lazarus/FP einbindbar / wie einzubinde
 
Das ist keine Macke, sondern das liegt einfach daran, dass tlhelp32 für 32 Bit geschrieben ist.
Wenn du eine 64-Bit-Version davon gefunden hast, und es immer noch nicht läuft, dann solltest du dich wundern.
Aber 32 und 64 Bit sind nunmal unterschiedlich. Da kannste nix machen.

Bist du dir sicher, dass die Daten nicht heil bei der DLL ankommen? Vielleicht liegt auch in der der Fehler. Oder ist es gar eine 32-Bit-DLL?


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:37 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz