![]() |
Funktion aus DLL einbinden
Ich tu mich gerade ein bisschen schwer dabei, eine einzelne Funktion aus einer DLL in meine DPR-Datei einzubinden.
Ich benötige nur ShellExecute und möchte wirklich ungern die komplette ShellAPI einbinden. Wie binde ich diese eine einzelne Funktion ein? Das hier funktioniert nicht :roll:
Delphi-Quellcode:
{$R *.res}
function ShellExecute; external 'shell32.dll' name 'ShellExecuteA'; |
AW: Funktion aus DLL einbinden
Kurze Google oder Forensuche:
![]() Oder: ![]()
Delphi-Quellcode:
type
TShellexecute = function(hWnd: HWND; Operation, FileName, Parameters, Directory: PChar; ShowCmd: Integer): HINST; stdcall; procedure TForm1.Button1Click(Sender: TObject); var hLib: cardinal; MyShellExecute: TShellexecute; begin hLib := LoadLibrary('shell32.dll'); if hLib <> 0 then begin @MyShellexecute := GetProcAddress(hLib, 'ShellExecuteA'); if not Assigned(MyShellexecute) then begin RaiseLastOSError; exit; end; end else begin RaiseLastOSError; exit; end; MyShellexecute(Form1.Handle, 'open', 'Notepad.exe', nil, nil, SW_NORMAL); end; |
AW: Funktion aus DLL einbinden
Hallo,
durch Einbinden einer Unit wird nicht die komplette Unit in die Exe reinkompiliert. Der Linker schmeißt nicht benutzte Funktionen raus. Der Code von Luckie ist natürlich trotzdem kleiner ... |
AW: Funktion aus DLL einbinden
Alternativ zu dem was Luckie gepostet hat (dynamische Bindung) gibt es noch die etwas weniger aufwendigere statische Bindung:
Delphi-Quellcode:
function Shellexecute(hWnd: HWND; Operation, FileName, Directory: PChar; ShowCmd: Integer): HINST; stdcall; external 'shell32.dll' name 'ShellExecuteA';
procedure TForm1.Button1Click(Sender: TObject); begin Shellexecute(Form1.Handle, 'open', 'Notepad.exe', nil, nil, SW_NORMAL); end; |
AW: Funktion aus DLL einbinden
Beide Quelltexte sind so nicht korrekt, da sie nicht unter allen Delphiversionen funktionieren.
Korrekt wäre:
Delphi-Quellcode:
Denn PChar ist je nach Delphiversion PAnsiChar oder PWideChar. Deshalb ist es falsch den Metatyp PChar bei API-Deklarationen zu benutzen.
{$IFDEF UNICODE}
function Shellexecute(hWnd: HWND; Operation, FileName, Directory: PWideChar; ShowCmd: Integer): HINST; stdcall; external 'shell32.dll' name 'ShellExecuteW'; {$ELSE} function Shellexecute(hWnd: HWND; Operation, FileName, Directory: PAnsiChar; ShowCmd: Integer): HINST; stdcall; external 'shell32.dll' name 'ShellExecuteA'; {$ENDIF} procedure TForm1.Button1Click(Sender: TObject); begin Shellexecute(Form1.Handle, 'open', 'Notepad.exe', nil, nil, SW_NORMAL); end; Wenn die oben geposteten Quelltexte unter Delphi 2009 oder höher benutzt würden, würde es einen Fehler geben, da nur das erste Zeichen an die Ansi-deklarierte Funktion übergeben würde. |
AW: Funktion aus DLL einbinden
PChar darf man gern verwenden, wenn die "Funktion" wirklich dynamisch ist.
Delphi-Quellcode:
Aber grundsätzlich stimmt es schon, bei den meisten WinAPIs -> xxxA mit PAnsiChar, xxxW mit PWideChar und xxx mit PChar (wird in den C++-Headern auch so gemacht und die Delphi-Headerübersetungen selber machen das auch schon länger so)
function Shellexecute(hWnd: HWND; Operation, FileName, Directory: PChar; ShowCmd: Integer): HINST; stdcall;
external 'shell32.dll' name {$IFDEF UNICODE}'ShellExecuteW'{$ELSE}'ShellExecuteA'{$ENDIF}; |
AW: Funktion aus DLL einbinden
Danke für eure Hilfe. Ich benutze nun folgende Deklaration mit Parameters.
Delphi-Quellcode:
function ShellExecute(hWnd: hWnd; Operation, FileName, Parameters, Directory: PWideChar; ShowCmd: Integer): HINST; stdcall; external 'shell32.dll' name 'ShellExecuteW';
|
AW: Funktion aus DLL einbinden
Zitat:
|
AW: Funktion aus DLL einbinden
Ich habe damals auch immer den konkreten Typ verwendet (nachdem ich es gelernt hatte), weil das andere nun einmal ein Metatyp war und ist. Das ist ja nicht neu, sondern war damals auch schon so.
Sich darauf zu verlassen, dass der immer auf Ansi zeigt, war da auch schon falsch. Ob PChar später wirklich Unicode wird, war natürlich nicht klar (war aber zu vermuten aus dem Delphiquelltext heraus), aber klar war, dass PAnsiChar und PWideChar bereits exakt definiert waren und heute ja weiter sind... Und wenn man mal in den Quelltext von Delphi 4 (!) schaut, da gab es die Unterscheidung ja auch schon...
Delphi-Quellcode:
Wenn man das dann damals aus Unwissenheit anders gemacht hat, ist das ja in Ordnung. Aber zu sagen, dass es korrekt war, finde ich nicht richtig. Unwissenheit schützt vor Strafe bzw. hier Problemen nicht.
function GetCommandLineA; external kernel32 name 'GetCommandLineA';
function GetCommandLineW; external kernel32 name 'GetCommandLineW'; function GetCommandLine; external kernel32 name 'GetCommandLineA'; // EDIT: Zitat:
|
AW: Funktion aus DLL einbinden
Seid doch so lieb und kommt wieder runter.
Die meisten von uns haben doch immer noch Char=AnsiChar-Leichen im Keller liegen, und den meisten ist klar, daß das Leichen sind. Nur falls irgendein Naivling daher kommt und Char in jedem Fall mit Byte übersetzt, sollte man mindestens da wo es notwendig ist mit AnsiChar oder WideChar oder Shortstring oder Ansistring oder .... typisieren. "korrekt" ist übrigens eine Eigenschaft, die stark von ihrer Umgebung abhängig ist. Es gibt ja genügend Beispiele für etwas was mal korrekt war und heute dieses Prädikat überhaupt nicht mehr verdient. Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:37 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz