![]() |
DLL-Parameter
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 |
Re: DLL-Parameter
Zitat:
Zitat:
|
Re: DLL-Parameter
Es handelt sich um eine C++ DLL.
Zitat:
Mich würde es trotzdem noch interessieren, wie ich Strings und Integer am einfachsten in ein Array of Char abfülle (und umgekehrt). |
Re: DLL-Parameter
Zitat:
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:
Delphi-Quellcode:
Integer sind 32bittig, ein char nur 8bittig, du müsstest schon genauer sagen, wie Integer in ein array of char gebracht werden sollen.
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; |
Re: DLL-Parameter
Erst mal besten Dank für die ausführliche Antwort. :thumb:
Zitat:
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]); |
Re: DLL-Parameter
Zitat:
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:
Zitat:
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. |
Re: DLL-Parameter
Zitat:
Delphi-Quellcode:
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?
//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)); Ist es egal ob ich eine Variable als PChar(StrVar1) oder als @StrVar1[1] übergebe? |
Re: DLL-Parameter
Kann mir hier noch jemand 'nen Tip geben? :oops:
DANKE |
Re: DLL-Parameter
Zitat:
![]() |
Re: DLL-Parameter
:hello: Besten Dank. Genau sowas habe ich gesucht!! :dancer:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:01 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