AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

DLL-Parameter

Ein Thema von TomDooley · begonnen am 4. Mai 2006 · letzter Beitrag vom 16. Mai 2006
Antwort Antwort
TomDooley

Registriert seit: 26. Jan 2004
124 Beiträge
 
#1

DLL-Parameter

  Alt 4. Mai 2006, 16:33
Hallo

Ich möchte eine DLL in mein Programm einbinden. Dabei ist mir die Behandlung der Parameter nich ganz klar. Nachfolgend ist die Deklaration der Funktion in der DLL und in meinem Programm ersichtlich:

Delphi-Quellcode:
dllFunction(char outParam[20], const char inParam[30]); //nur Beispiel, es sind mehrer Param. vorhanden

delphiFunct(outParam : PChar; inParam PChar); stdcall; //nur Beispiel, es sind mehrer Param. vorhanden

Ich habe die Parameter nun aber nicht als Zeiger vorliegen sondern als String und Integer.

- darf ich als Output-Parameter (VAR-Parameter) String-Adressen verwenden (z.B @StringVar) oder
muss ich die Strings erst in Array of Char abfüllen und dann die Array-Adresse übergeben (z.B @CharVar[0])?

Wie fülle ich die Strings und Integers möchlichst einfach in ein Array of Char ab?

Gibt's irgendwo ein Tutorial oder sowas zur Benutzung von DLL's?

Danke und Gruss

Tom
  Mit Zitat antworten Zitat
Frickeldrecktuxer_TM
(Gast)

n/a Beiträge
 
#2

Re: DLL-Parameter

  Alt 4. Mai 2006, 18:38
Zitat von TomDooley:
Delphi-Quellcode:
dllFunction(char outParam[20], const char inParam[30]); //nur Beispiel, es sind mehrer Param. vorhanden

delphiFunct(outParam : PChar; inParam PChar); stdcall; //nur Beispiel, es sind mehrer Param. vorhanden
Du möchtest übereinstimmende Calling Conventions benutzen. "Ohne alles" ist es in C nicht stdcall, sondern cdecl.

Zitat von TomDooley:
darf ich als Output-Parameter (VAR-Parameter) String-Adressen verwenden (z.B @StringVar) oder
muss ich die Strings erst in Array of Char abfüllen und dann die Array-Adresse übergeben (z.B @CharVar[0])?
@StringVar[1] geht auch. Beim outParam sollte genug Speicher vorhanden sein (SetLength() bei AnsiStrings).
  Mit Zitat antworten Zitat
TomDooley

Registriert seit: 26. Jan 2004
124 Beiträge
 
#3

Re: DLL-Parameter

  Alt 5. Mai 2006, 08:31
Es handelt sich um eine C++ DLL.

Zitat:
@StringVar[1] geht auch. Beim outParam sollte genug Speicher vorhanden sein (SetLength() bei AnsiStrings).
Das heisst, Object-Pascal-Strings sind mit C++-Strings (bzw. C++ Char-Arrays) kompatibel?

Mich würde es trotzdem noch interessieren, wie ich Strings und Integer am einfachsten in ein Array of Char abfülle (und umgekehrt).
  Mit Zitat antworten Zitat
Frickeldrecktuxer_TM
(Gast)

n/a Beiträge
 
#4

Re: DLL-Parameter

  Alt 5. Mai 2006, 15:25
Zitat von TomDooley:
Zitat:
@StringVar[1] geht auch. Beim outParam sollte genug Speicher vorhanden sein (SetLength() bei AnsiStrings).
Das heisst, Object-Pascal-Strings sind mit C++-Strings (bzw. C++ Char-Arrays) kompatibel?
Jein.
AnsiStrings von Pascal sind nichts anderes als eine KEtte von Zeichen, die nullterminiert ist, also das gleiche wie ein C-String-Literal (und alles, womit die Funktionen aus string.h arbeiten können). Der Unterschied besteht darin, daß der AnsiString zusätzlich noch in vier Bytes *vor* dem String die Länge des strings sowie einen Referenzzähler hat, was bei C-Strings nicht so ist. Die Compiler-Magic sorgt aber dafür, daß du davon nichts mitbekommst, und deswegen bekommst du mit StrVariable[1] das erste Zeichen des Strings. Alle weiteren Zeichen folgen in aufsteigender Speicheradresse bis zum Nullterminator. Mit @StrVariable[1] hast du also einen Pointer auf das erste Zeichen eines nullterminierten Strings, also genau das, was C-String-Literale sind.
Mit C++-Strings (std::string) sind sie von vorne bis hinten nicht kompatibel, auch wenn man einem std::string ein char * zuweisen kann, was aber eine Eigenschaft der Klasse (std::string ist eine echte Klasse, nicht Compiler-Magic wie AnsiStrings in Delphi) ist.

Zitat von TomDooley:
Mich würde es trotzdem noch interessieren, wie ich Strings und Integer am einfachsten in ein Array of Char abfülle (und umgekehrt).
Einen String in ein array of char:
Delphi-Quellcode:
var
  a: array of char;
  s: String;
begin
  s := 'SomeText';
  SetLength(a, Length(s) + 1);
  for i := 0 to Length(a) - 2 do
    a[i] := s[i+1];
  a[High(a)] = #0;

//oder alternativ:
  s := 'SomeText';
  SetLength(a, Length(s) + 1);
  MemCopy(@a[0], @s[1], Length(a) - 1);
  a[High(a)] = #0;
end;
Integer sind 32bittig, ein char nur 8bittig, du müsstest schon genauer sagen, wie Integer in ein array of char gebracht werden sollen.
  Mit Zitat antworten Zitat
TomDooley

Registriert seit: 26. Jan 2004
124 Beiträge
 
#5

Re: DLL-Parameter

  Alt 5. Mai 2006, 15:54
Erst mal besten Dank für die ausführliche Antwort.

Zitat:
Integer sind 32bittig, ein char nur 8bittig, du müsstest schon genauer sagen, wie Integer in ein array of char gebracht werden sollen.
Wie oben beschrieben habe die meine Variablen nicht nur als String sondern auch als integer vorliegen. Eigentlich habe ich das selbe Problem wie zuvor bei den Strings... Wie muss ich einen Integer einer Funktion übergeben, welche einen Parameter vom Typ PChar erwartet? Ich nehme mal an, @IntegerVar dürfte nicht funktionieren, oder?

Ich denke, ich könnte den Integer nun zuerst in einen String konvertieren und dann analog zu Deiner Problemlösung verwenden... Da die C++ DLL ein Char-Array erwartet, frage ich mich nun, ob ich den Integer nicht auch so übergeben könnte:
Delphi-Quellcode:
Pseudocode:
  intVar : integer;
  charArr : array[0..20] of char;

  intVar := 1234;

  charArr := IntToCharArray(intVar); //charArr[0]=1, charArr[1]=2, etc.

  delphiFunct(charArr[0]);
  Mit Zitat antworten Zitat
Frickeldrecktuxer_TM
(Gast)

n/a Beiträge
 
#6

Re: DLL-Parameter

  Alt 5. Mai 2006, 16:38
Zitat von TomDooley:
Zitat:
Integer sind 32bittig, ein char nur 8bittig, du müsstest schon genauer sagen, wie Integer in ein array of char gebracht werden sollen.
Wie oben beschrieben habe die meine Variablen nicht nur als String sondern auch als integer vorliegen. Eigentlich habe ich das selbe Problem wie zuvor bei den Strings... Wie muss ich einen Integer einer Funktion übergeben, welche einen Parameter vom Typ PChar erwartet? Ich nehme mal an, @IntegerVar dürfte nicht funktionieren, oder?
Jein (schon wieder ).
Es würde syntaktisch ohne weiteres gehen und sogar semantisch, solange dann die C-Funktion nicht weiter ausliest als parameter+3, weil das das letzte Byte des Integers wäre. Mit @IntegerVar bekommst du einen Pointer auf das unterste Byte des Integers, danach kommen noch drei weitere, allerdings kein Nullterminator am Ende. Der Rest ist analog, du könntest in der C-Funktion mit inParam[0] bis inParam[3] auf die einzelnen Bytes des Integers zugreifen (wenn du's ausprobieren möchtest und verwirrende Ergebnisse bekommst, beachte die Endianness auf Intel-Systemen, die sind nämlich LittleEndian).
Aber das ergibt nunmal nicht sinderlich viel Sinn, weil man üblicherweise nicht mit den einzelnen Bytes eines Integers rechnet. Wenn du also die gesamte 32bit-Zahl haben willst, müsstest du sie in der C-Funktion entweder aus den vier Einzelbytes wieder zusammensetzen oder durch einen Typecast in einen 32bit-Typ (je nach Architektur und Compiler kann das int oder long int sein) drauf zugreifen. Einfacher wäre es hier, einfach eine zweite Funktion in C einzuführen, die als Parameter kein Byte-Array (char *) annimmt, sondern einen Integer (oder ein Integer-Array).

Zitat von TomDooley:
Ich denke, ich könnte den Integer nun zuerst in einen String konvertieren und dann analog zu Deiner Problemlösung verwenden...
Ich nehme an du meinst IntToStr()? Das wäre eine andere Problemstellung. Da übergibst du ja nicht den Integer als Integer, sondern die Repräsentation der Zahl in einem willkürlichen (menschenlesbaren) System, nämlich als String "123".

Zitat von TomDooley:
Da die C++ DLL ein Char-Array erwartet, frage ich mich nun, ob ich den Integer nicht auch so übergeben könnte:
Delphi-Quellcode:
//...
  charArr := IntToCharArray(intVar); //charArr[0]=1, charArr[1]=2, etc.
Das kommt ganz darauf an, was du vorhast, und ob dieses Vorgehen sinnvoll ist. Dabei hättest du jede Stelle im Dezimalsystem in einem eigenen Byte. Wenn du das so haben willst, wäre das eine (weitere) mögliche Lösung (vorrausgesetzt die Funktion in der DLL erkennt, ob es sich beim übergebenen Parameter um einen String oder einen Integer handelt).
Jetzt kennst du drei (vier) verschiedene Möglichkeiten, die alle "irgendwie" den Integer an die Funktion übergeben, aber jeweils in verschiedenen Datenformaten und zugänglich über verschiedene Zugriffsarten. Es kommt einzig und allein darauf an, was du damit machen willst. Du musst also entscheiden, was praktikabel für deine spezielle Anwendung ist. Willst du mit der Zahl rechnen wäre es unsinnig, sie im Delphi-Teil in ihre Dezimalstellen aufzudröseln, zu übergeben und in der DLL aus den Dezimalstellen wieder einen Integer zusammenzubasteln, damit man in der DLL damit rechnen kann.
  Mit Zitat antworten Zitat
TomDooley

Registriert seit: 26. Jan 2004
124 Beiträge
 
#7

Re: DLL-Parameter

  Alt 12. Mai 2006, 13:14
Zitat:
Einfacher wäre es hier, einfach eine zweite Funktion in C einzuführen, die als Parameter kein Byte-Array (char *) annimmt, sondern einen Integer (oder ein Integer-Array).
Das kann ich leider nicht, da ich die DLL von extern bekommen habe. Hier nun mal ein Beispiel wie ich es jetzt gelöst habe:

Delphi-Quellcode:
//Definition in der DLL
long dllFunction(char* outParam[20], char* inoutParam[20], const char inParam[20]);

//Definition der Delphi-Function
delphiFunct(outParam PChar; inoutParam PChar; const inParam PChar) : integer; stdcall;
@delphiFunct := GetProcAddress(dll,'dllFunction');

//Meine Implementation
StrVar1, StrVar2, StrVar3 : String;
result := delphiFunct(PChar(StrVar1), PChar(StrVar2), PChar(StrVar3));
Ich entnehme der Definition, dass die C++ DLL Char-Arrays erwartet. Soll ich meine Implemenation so belassen oder meine Strings in Char-Arrays konvertieren und dann mit @CharArrVar1[0] etc. der Funktion übergeben?

Ist es egal ob ich eine Variable als PChar(StrVar1) oder als @StrVar1[1] übergebe?
  Mit Zitat antworten Zitat
TomDooley

Registriert seit: 26. Jan 2004
124 Beiträge
 
#8

Re: DLL-Parameter

  Alt 15. Mai 2006, 10:51
Kann mir hier noch jemand 'nen Tip geben?

DANKE
  Mit Zitat antworten Zitat
Frickeldrecktuxer_TM
(Gast)

n/a Beiträge
 
#9

Re: DLL-Parameter

  Alt 15. Mai 2006, 10:59
Zitat von TomDooley:
Ist es egal ob ich eine Variable als PChar(StrVar1) oder als @StrVar1[1] übergebe?
Dieses Tutorial erklärt dir prima den Unterschied zwischen den verschiedenen Möglichkeiten, einen C-String aus einem AnsiString zu besorgen.
  Mit Zitat antworten Zitat
TomDooley

Registriert seit: 26. Jan 2004
124 Beiträge
 
#10

Re: DLL-Parameter

  Alt 16. Mai 2006, 16:12
Besten Dank. Genau sowas habe ich gesucht!!
  Mit Zitat antworten Zitat
Antwort Antwort


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 15:19 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