AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Wer kann mir diese C Funktion uebersetzen?
Thema durchsuchen
Ansicht
Themen-Optionen

Wer kann mir diese C Funktion uebersetzen?

Ein Thema von mika · begonnen am 29. Jan 2006 · letzter Beitrag vom 6. Feb 2006
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#11

Re: Wer kann mir diese C Funktion uebersetzen?

  Alt 30. Jan 2006, 19:57
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.

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:
PParameterStructure = ^TParameterStructure;
TParameterStructure = Record
  one,
  two,
  three,
  four: double;
End;
Die Methode die aufgerufen wird sieht folgendermaßen aus:
Delphi-Quellcode:
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
In meinem Testprogramm das die DLL aufruft ist in meiner "Api"-Unit folgendes angelegt!
Delphi-Quellcode:
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';
Und bei dem Button mit dem ich den ganzen Kram teste:
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?
:: don't Panic ::
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#12

Re: Wer kann mir diese C Funktion uebersetzen?

  Alt 30. Jan 2006, 20:37
Zitat von mika:
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?
Nein. Das macht der Compiler für dich. Bei DLLs ist unter Windows StdCall geläufiger als Cdecl.

Zitat:
Die Methode die aufgerufen wird sieht folgendermaßen aus:
Delphi-Quellcode:
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
Ich gehe mal davon aus, dass das nur ein Pseudo-Code ist, denn der Compiler wird dir da einiges wegoptimieren, weil es Unnütz ist.

Zitat:
In meinem Testprogramm das die DLL aufruft ist in meiner "Api"-Unit folgendes angelegt!
Delphi-Quellcode:
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';
Da es sich um eine Delphi-Unit handelt, kannst du auch beim "Var Parameter" den Typ mit angeben. Dann kann schon mal nichts mehr mit falschen Parametern schief laufen, was du ja im nächsten Code-Block gliech mal falsch machst.

Zitat:
Und bei dem Button mit dem ich den ganzen Kram teste:
Deine Funktion möchte einen TParamStructure in der DLL. Da du aber diese Information in der Import-Unit verheimlichst und ein allgemeingültigen veränderbaren Parameter möchtest, akzeptiert der Compiler hier natürlich auch einen Zeiger(Var) auf einen Zeiger auf eine TParamStructure, was aber falsch ist, denn die DLL mag ja nur einen Zeiger(Var) auf eine TParamStructure. Also ein "Zeiger auf" weniger.

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:
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';
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).
  Mit Zitat antworten Zitat
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#13

Re: Wer kann mir diese C Funktion uebersetzen?

  Alt 30. Jan 2006, 20:45
Hallo jbg,

hast recht das ganze ist nur pseudocode aber es geht ja auch nur ums verständnis


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]
:: don't Panic ::
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#14

Re: Wer kann mir diese C Funktion uebersetzen?

  Alt 30. Jan 2006, 21:17
Zitat von mika:
Sollte ich Const nur einsetzen damit es verständlicher ist (in der DLL) oder hat es auch noch weitere Vorteile?
Es ist verständlicher. Bei "var" oder "out" geht man immer davon aus, dass der Parameter verändert wird. Gibt man nichts an, so muss der Compiler Code einfügen, der den Record kopiert, damit Änderungen in der Funktion nicht auf die übergebene Variable Auswirkungen haben, was ineffizient ist, wenn man es nicht braucht.
  Mit Zitat antworten Zitat
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#15

Re: Wer kann mir diese C Funktion uebersetzen?

  Alt 30. Jan 2006, 21:24
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!
:: don't Panic ::
  Mit Zitat antworten Zitat
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#16

Re: Wer kann mir diese C Funktion uebersetzen?

  Alt 6. Feb 2006, 20:46
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

Also hier mal n bisschen C Source der alten DLL:
DLL Header Datei
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_ */
DLL-Code
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

Jetzt mal n bisschen Beispielcode von mir

Delphi-Quellcode:
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.
Die Methode AddtoLogfile schreibt mir das ganze in eine textdatei, was auch funktioniert aber die Werte (sollten alle 0 sein)
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!
:: don't Panic ::
  Mit Zitat antworten Zitat
Benutzerbild von mika
mika

Registriert seit: 25. Okt 2002
176 Beiträge
 
Delphi 6 Professional
 
#17

Re: Wer kann mir diese C Funktion uebersetzen?

  Alt 6. Feb 2006, 21:14
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

:: don't Panic ::
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:42 Uhr.
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