|
| Problem med DLL Fra : Thomas Jakobsen |
Dato : 28-11-00 23:50 |
|
Hejsa. Er der nogen der kan hjælpe mig med nedenstående kode. Jeg får
en access violation, når jeg forsøger at overføre en værdi til min
funktion som er beliggende i DLL'en. På forhånd tak.
<dll>
library Test;
uses
SysUtils,
Classes;
{$R *.RES}
function TestFunction(X: Integer): integer; stdcall; export;
begin
TestFunction := X * 2;
end;
exports
TestFunction;
begin
end.
</dll>
<program>
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
function TestFunction(X: Integer): Integer; external 'Test.dll';
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(IntToStr(TestFunction(15)));
end;
end.
</program>
| |
N/A (29-11-2000)
| Kommentar Fra : N/A |
Dato : 29-11-00 09:45 |
|
| |
Jan Pedersen - JPSof~ (29-11-2000)
| Kommentar Fra : Jan Pedersen - JPSof~ |
Dato : 29-11-00 09:45 |
|
"Thomas Due" <noname@nowhere.net> skrev i en meddelelse
news:902bql$i2t$1@news.inet.tele.dk...
> Hej Thomas,
>
> For det første så skal du ikke have en export bag efter function
> erklæringen, når du har
> en export sektion. Dernæst skal du også programmet sætte stdcall på.
>
> // dll
> [SNIP]
> > function TestFunction(X: Integer): integer; stdcall; export; <--- Fjern
> denne ---<---<
> > begin
> > TestFunction := X * 2;
> > end;
> > </dll>
>
> > <program>
> [SNIP]
> > implementation
> >
> > function TestFunction(X: Integer): Integer; external 'Test.dll';
>
> Indsæt stdcall før external, sådan her:
>
> function TestFunction(X: Integer): Integer; stdcall; external 'Test.dll';
>
> DLL programmering er meget sårbar og meget følsom. Hvis ikke tingene er
> gjort
> helt korrekt får du en fejl, og den kan godt være utrolig svær at finde.
Så
> vær omhyggelig :)
>
> Mvh
> Thomas Due
>
>
Hej Thomas.
Den måde Thomas har vist dig at kalde en .dll fil på, kaldes statisk
binding.
Dvs. at koden bliver bundet til din .exe fil, og at programmet ikke kan køre
hvis
denne mangler.
En anden måde at benytte en .dll fil på. er dynamisk binding.
Ved denne måde indlæser man først .dll filen (eller den funktion man skal
bruge)
når man aktuelt skal bruge den.
Et eks.:
procedure LoadDLL_dynamic;
type
TTestFunction = function(X: integer): integer;
var
DLLInstance: THandle;
DLLFunction: TTestFunction;
begin
DLLInstance:= LoadLibrary('MinDLL.dll');
if DLLInstance = 0 then
begin
MessageDlg('Kunne ikke indlæse filen MinDLL.dll', mtError, [mbOK], 0);
exit;
end;
@DLLFunction:= GetProcAddress(DLLInstance, 'TestFunction');
if @DLLFunction <> NIL then
ShowMessage('Resultat fra .dll funktion: ' + IntToStr(DLLFunction(10)))
else
MessageDlg('Kunne ikke finde funktionskald i filen MinDLL.dll', mtError,
[mbOK], 0);
FreeLibrary(DLLInstance);
end;
Fordele og ulemper ved de to metoder:
Statisk binding:
---------------------
Programmet starter langsommere.
..DLL filen er i memory under hele programkørslen,
dvs. dårlig udnyttelse memory.
Programmet kan ikke startes uden denne.
Let at bruge.
Dynamisk binding:
-------------------------
Indlæser først .DLL fil i memory når den skal bruges.
Programmet starter hurtigere.
..DLL filen er kun i memory så lang tid du skal bruge den,
dvs. bedre udnyttelse af memory.
Programmet kan sagtens køre uden .DLL filen.
Ikke så let at bruge som statisk binding.
-Jan
| |
|
|