![]() |
Probleme beim dynamischen Einbinden einer DLL
Hi Leute,
irgentwie habe ich gerade ne Denkblockade und seh den Wald vor lauter Bäumen nicht. Hoffe Ihr könnt mir weiter helfen. Ich will eine Function aus einer DLL dynamisch laden und ausführen. Die DLL ist in C++ geschrieben :
Delphi-Quellcode:
Wenn ich die DLL statisch einbinde funktioniert alles reibungslos.
In der Dll gibts genau eine Funktion, die da wäre:
int CreateSqlImportScript( char *pJournalFile, char *pSqlScript, int iStandortID, int iStammdaten, char *pErrorText ) (* Kurze Erklärung: pJournal: StringRef, der den Pfad des Journalfiles angibt. pSqlScript: StringRef, der die Ausgabedatei angibt. iStandortID: StandortID iStammdaten: 0 = ohne Stammdaten, 1 = mit pErrorText: StringRef, der eventuell Fehlermeldungen enthält ( Speicher muß alloziert sein ( min. 1014 bytes ) *) Jetzt habe ich meine Aktionen bezüglich dieser DLL in eine seperate Klasse ausgelagert(s. Code)
Delphi-Quellcode:
Nur zur Vollständigkeit, der Code der die Klasse erzeugt und Start aufruft :
unit VectronImport;
interface uses Classes, SysUtils; const cDLLName = 'ImpVecEJ.dll'; cSplit = '|'; cFilterField : String = '[F]'; cDateField : String = '_DT'; cOk = 1; cErr_Unknown = -1; cErr_ImportFileNotFound = -2; cErr_ImportFileLoadError = -3; cErr_DllFileNotFound = -4; cErr_DllLoad = -5; type TImportDll = function (InputFile : PChar; OutputFile : PChar; SOrtID : Integer; Stammdaten : Integer; sError : PChar) : integer; stdcall; TOnProgress = procedure(Sender: TObject; const Ready: Byte) of object; TVectronImport = Class private FImpFile : String; FDllDir : String; FstrLFile : TStringList; hDll : Cardinal; FProzReady : Byte; // fOnProgress : TOnProgress; ImportDll : TImportDll; pRes : PChar; sErr : String; function CheckStartConditions : Longint; protected {} public Constructor Create; Destructor Destroy; override; property ImportFile : String read FImpFile write FImpFile; property DllDir : String read FDllDir write FDllDir; property OnProgress : TOnProgress read fOnProgress write fOnProgress; function Start : Longint; end; implementation uses Windows; { TVectronImport } constructor TVectronImport.Create; begin inherited; FImpFile := ''; FDllDir := ''; hDll := 0; ImportDll := Nil; FstrLFile := TStringList.Create; FProzReady := 0; end; destructor TVectronImport.Destroy; begin if @ImportDll <> Nil then @ImportDll := Nil; if hDLL <> 0 then begin FreeLibrary(hDll); hDLL := 0; end; FreeAndNil(FstrLFile); inherited; end; function TVectronImport.CheckStartConditions: Longint; Var sTmp : String; begin if not FileExists(FImpFile) then begin result := cErr_ImportFileNotFound; exit; end; sTmp := IncludeTrailingBackslash(FDllDir)+cDLLName; if not FileExists(sTmp) then begin result := cErr_DllFileNotFound; exit; end; try hDll := LoadLibrary(PChar(sTmp)); if hDll > 0 then begin @ImportDll := GetProcAddress(hDll,PChar('CreateSqlImportScript')); result := cOk end else Result := cErr_DllLoad; except Result := cErr_DllLoad; end; end; function TVectronImport.Start: Longint; Var iRes : Longint; begin iRes := CheckStartConditions; if iRes < cOk then begin result := iRes; exit; end; if @ImportDll = nil then exit; GetMem(pRes, 1014); try iRes := ImportDll(pchar(FImpFile),Pchar('d:\dyndll_export.txt'),12,0,pRes); sErr := String(pRes); finally FreeMem(pRes); pRes := Nil; end; result := iRes; // jetzt beim verlassen der Unit(Debuggen) kommt eine Schutzverletzung beim Schreiben end; end.
Delphi-Quellcode:
Wie schon als Kommentar in der Function Start erwähnt, tritt beim verlassen der function Start eine Zugriffsverletzung beim Schreiben auf!
procedure TfrmMain.cmd_TestClick(Sender: TObject);
Var VecImp : TVectronImport; iTmp : Longint; begin VecImp := TVectronImport.Create; try VecImp.ImportFile := ed_VecExpFile.Text; VecImp.DllDir := sAppDir; iTmp := VecImp.Start; finally FreeAndNil(VecImp); end; showmessage(inttostr(iTmp)); end; Interessant ist : Lässt man die Zeile "pRes := Nil;" weg, ist die Schutzverletzung an einer gültigen Speicheradresse, mit der Zeile ist die Schutzverletzung bei Adresse 000000000. Was übersehe ich hier gerade ? Danke und Gruß Data |
Re: Probleme beim dynamischen Einbinden einer DLL
ersetze mal das
Delphi-Quellcode:
durch
sErr := String(pRes);
Delphi-Quellcode:
bei deiner Variante wird wohl der String sErr auf einen Speicherblock zeigen, der kurz darauf freigegeben wird...
sErr := StrPas(pRes);
|
Re: Probleme beim dynamischen Einbinden einer DLL
Danke, genau das wars. :oops:
:dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:20 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