![]() |
Re: Wer kann mir diese C Funktion uebersetzen?
So, ich habe mir gedacht ich kann meine DLL ja schon mal umbauen und schreib
mir selber noch n kleines Testprogramm um die ganze Sache einmal auszuprobieren aber irgendwie klappt das auch nicht so ganz. :evil: Ich bekomms immer noch nicht hin die Parameter auszulesen. Da ich die Aufrufkonvention jetzt ja auf cdecl geändert habe muss ich mich doch auch im "Aufrufenden" Programm um die Speicherverwaltung der Parameter kümmern oder? In meiner DLL habe ich folgenden Record deklariert
Delphi-Quellcode:
Die Methode die aufgerufen wird sieht folgendermaßen aus:
PParameterStructure = ^TParameterStructure;
TParameterStructure = Record one, two, three, four: double; End;
Delphi-Quellcode:
In meinem Testprogramm das die DLL aufruft ist in meiner "Api"-Unit folgendes angelegt!
Function PassParamFunction(Var Parameter: TParamStructure): Double; cdecl;
Var Wert1, Wert2, Wert3, Wert4: Double; Begin Wert1 := Parameter.one; Wert2 := Parameter.two; Wert3 := Parameter.three; Wert4 := Parameter.four; Result := 0; End
Delphi-Quellcode:
Und bei dem Button mit dem ich den ganzen Kram teste:
PParameterStructure = ^TParameterStructure;
TParameterStructure = Record one, two, three, four: double; End; Function PassParamFunction(Var Parameter): Double; cdecl; implementation Function PassParamFunction(Var Parameter): Double; cdecl; external 'test.dll';
Delphi-Quellcode:
Procedure TestIt;
Var Parameter: PParameterStructure; Begin GetMem(Parameter, SizeOf(TParameterStructure)); Parameter.One := 12; Parameter.Two := 23; Parameter.Three := 34; Parameter.Four := 45; PassParamFunction(Parameter); FreeMem(Parameter); End Wisst ihr da weiter? |
Re: Wer kann mir diese C Funktion uebersetzen?
Zitat:
Zitat:
Zitat:
Zitat:
Das mit dem GetMem/FreeMem kannst du dir auch sparen, wenn du einfach eine lokale Variable vom Typ TParamStructure anlegst. Damit ist auch gleich sichergestellt, dass du kein Speicherleck produzierst. Die Import-Unit muss also besser so aussehen:
Delphi-Quellcode:
Und wenn du die ParameterStructure-Felder nicht verändern willst, kannst du aus dem "var" auch ein "const" machen (dann aber auch in der DLL daraus ein "const" machen).
type
PParameterStructure = ^TParameterStructure; TParameterStructure = record One, Two, Three, Four: Double; end; function PassParamFunction(var Parameter: TParameterStructure): Double; cdecl; implementation function PassParamFunction(var Parameter: TParameterStructure): Double; cdecl; external 'test.dll'; |
Re: Wer kann mir diese C Funktion uebersetzen?
Hallo jbg,
hast recht das ganze ist nur pseudocode aber es geht ja auch nur ums verständnis :D alsooo, du hast recht, nachdem ich in meinem aufrufendem programm mitgeteilt habe das der Var Parameter vom Typ TParameterStructure ist klappt auch das entgegennehmen der Parameter sehr gut. Ich werde jetzt mal weitertesten, meld mich gleich mal wieder.... [edit] Ich will in meiner DLL die Parameter nicht verändern sondern nur entgegennehmen. Sollte ich Const nur einsetzen damit es verständlicher ist (in der DLL) oder hat es auch noch weitere Vorteile? [/edit] |
Re: Wer kann mir diese C Funktion uebersetzen?
Zitat:
|
Re: Wer kann mir diese C Funktion uebersetzen?
Alles klar, hab das jetzt auch auf Const geändert und innerhalb meiner Testumgebung funktioniert das ganze auch
sehr gut. Fragt sich bloss wie es mit der richtigen Anwendung aussieht :? Danke für die Hilfe! :thumb: |
Re: Wer kann mir diese C Funktion uebersetzen?
Hallo Delphi Praxis,
inzwischen habe ich das ganze mit der Anwendung die es zu unterstützen gilt getestet und bin leider nicht weitergekommen :-( Da ich jedoch nun alles hier bei mir habe um zu testen und auch "Fetzen" der alten C-DLL gefunden habe die es zu ersetzen gilt hoffe ich das ich mit eurer Hilfe das ganze doch noch abeschliessen kann :wink: Also hier mal n bisschen C Source der alten DLL: DLL Header Datei
Code:
DLL-Code
#ifndef _DLL_H_
#define _DLL_H_ #include <Windows.h> #ifdef __cplusplus extern "C" { #endif #if BUILDING_DLL # define DLLIMPORT __declspec (dllexport) #else /* Not BUILDING_DLL */ # define DLLIMPORT __declspec (dllimport) #endif /* Not BUILDING_DLL */ #ifndef DLL_CALL #define DLL_CALL __stdcall #endif struct LSLSimpleParams { int productCode; HWND windowsHandle; }; DLLIMPORT double DLL_CALL lsl_getNumberOfDays(struct LSLSimpleParams *parameters); #ifdef __cplusplus } #endif #endif /* _DLL_H_ */
Code:
DLLIMPORT double DLL_CALL lsl_getNumberOfDays(struct LSLSimpleParams *parameters)
{ double nofDays = 9999; int atLeastOneLicenceFound = 0; if(!parameters || parameters->productCode > maxProductKey) nofDays = -9999; return nofDays; } Diese Funktionen brauch ich zwar in meiner neuen DLL noch nicht, sind aber ein Beispiel für eine Funktionierende Funktion in der alten DLL! Mir geht es nur um die Parameterübergabe da ich das neue Programm schon soweit habe das es einige von mir gewünschte Funktionen aufruft, der Code darin ausgeführt wird und weiterläuft. Das einzige was ich nicht schaffe sind die Parameter auszulesen! Ich bekomme ja einen Pointer auf eine Struktur. Soweit ich es dem C Code entnehmen kann muss ich einfach nur diese Struktur auslesen, ich muss doch keinen Specherplatz allokieren oder freigeben :gruebel: Jetzt mal n bisschen Beispielcode von mir
Delphi-Quellcode:
Die Methode AddtoLogfile schreibt mir das ganze in eine textdatei, was auch funktioniert aber die Werte (sollten alle 0 sein)
library intelliDLL;
{ Wichtiger Hinweis zur DLL-Speicherverwaltung: ShareMem muß sich in der ersten Unit der unit-Klausel der Bibliothek und des Projekts befinden (Projekt- Quelltext anzeigen), falls die DLL Prozeduren oder Funktionen exportiert, die Strings als Parameter oder Funktionsergebnisse übergeben. Das gilt für alle Strings, die von oder an die DLL übergeben werden -- sogar für diejenigen, die sich in Records und Klassen befinden. Sharemem ist die Schnittstellen-Unit zur Verwaltungs-DLL für gemeinsame Speicherzugriffe, BORLNDMM.DLL. Um die Verwendung von BORLNDMM.DLL zu vermeiden, können Sie String- Informationen als PChar- oder ShortString-Parameter übergeben. } uses SysUtils, Classes; Type TWriteEventStructure = Record entityID, lkNumber, locationNumber, resourceNumber, vWochenTag, vAnzeigeStd, vAnzeigeMin, vAnzeigeSek: Integer; fHandle: THandle; End; Function eventEntityCreate(Const Parameter: TWriteEventStructure): Double; cdecl; Begin AddToLogfile(eventLogName, 'Methode : DLL-Methode des Events' + #13#10 + 'EventNr : '+IntToStr(uDMEvents.evtEntityCreate) + #13#10 + 'entityID : '+IntToStr(Parameter.entityID) + #13#10 + 'lkNumber : '+IntToStr(Parameter.lkNumber) + #13#10 + 'locationNumber: '+IntToStr(Parameter.locationNumber) + #13#10 + 'resourceNumber: '+IntToStr(Parameter.resourceNumber) + #13#10 + 'vWochenTag : '+IntToStr(Parameter.vWochenTag) + #13#10 + 'vAnzeigeStd : '+IntToStr(Parameter.vAnzeigeStd) + #13#10 + 'vAnzeigeMin : '+IntToStr(Parameter.vAnzeigeMin) + #13#10 + 'vAnzeigeSek : '+IntToStr(Parameter.vAnzeigeSek) ); Result := 0; End; // Alle exportierten Methoden dieser DLL exports eventEntityCreate; Function onExitDLL: Boolean; Begin Result := True; End; begin // Neue Ausstiegsprozedur registrieren AddTerminateProc(onExitDLL); end. wirken auf mich wie uninitialsiert, es sind irgendwelche Werte (interessant war auch das die gleich blieben, das heisst Aufrufendes Programm wurde 3 mal gestartet -> Funktion 3 mal aufgerufen -> jedes mal Quatsch, aber der gleiche). Vielleicht könnt ihr mir noch weiterhelfen bin ich echt am verzweifeln! Habs schon mit stdcall als Aufrufkonvention probiert oder mit nem Packed Record als Struktur aber einfach kein erfolg! Bin über jeden Tip dankbar! |
Re: Wer kann mir diese C Funktion uebersetzen?
Hmmm ich bin grad am testen und es sieht aus als ob es so wie es in Beitrag Nummer 2 von marabu beschrieben wird funktioniert.
Schreib gleich mehr muss testen :-D :dp: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:35 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-2025 by Thomas Breitkreuz