Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   String/Char-Pointer aus C# DLL korrekt auslesen (https://www.delphipraxis.net/178329-string-char-pointer-aus-c-dll-korrekt-auslesen.html)

Testsieger 2. Jan 2014 09:25

String/Char-Pointer aus C# DLL korrekt auslesen
 
Hallo,
erst mal ein frohes Neues Jahr.

Ich habe leider noch eine „ungelöste“ Aufgabe aus dem alten Jahr:

Die Ausgangssituation ist folgende:
Ich habe in mein Delphi-Programm eine C#-DLL eingebunden, über die eine eigene Datenbank gemanagt wird. Zwischen meinem Programm und der DLL müssen also jede Menge Daten ausgetauscht werden. Dabei handelt es sich um numerische und alphanumerische Daten, die als Pointer übergeben werden müssen. Alle numerischen Daten werden problemlos wechselseitig ausgetauscht.
Die Übergabe von Strings als „Pansichar“ funktioniert auch in eine Richtung: Übergabe von Delphi an die DLL. Nur umgekehrt hapert es. Ich kann keine Daten sauber auslesen und weiterverarbeiten.
Dabei gibt es DLL-Routinen, die aufeinander aufbauen und korrekt funktionieren. Beispiel:
Ich lese über eine Funktion eine Pansichar-Variable ein und übergebe den Inhalt (bzw. die Pointeradresse) wieder an eine andere DLL-Routine, die dann auch richtig ausgeführt wird. Das Problem liegt also „nur“ im Delphi-Programm.

Hier 2 Basisfunktionen der DLL, die nacheinander aufgerufen werden:
Function GetVarInfo(hFile:integer;iVar:Integer;out varname:pansichar;out varinfo:pinteger):Integer;stdcall; external 'c:\test\io32.dll' name 'GetVarInfo';
Function GetVarHandle(hFile:Integer;varname:pansichar;var varHandle:double):Integer;stdcall; external 'c:\test\io32.dll' name 'GetVarHandle';

“Getvarinfo” liefert den Variablennamen, den man an “Getvarhandle” wieder übergibt. Mit diesem
Variablenamen werden in weiteren Funktionen die Daten der Datenbank abgerufen. Das funktioniert auch, aber ich kann mir den Variablenamen nicht richtig anzeigen lassen.

Hier meine Aufruf-Routinen:

var hFile,iVar:integer;
varname2:pansichar;
varhandle:double;
varinfo:pinteger;
zwst1:string[120];
begin
fehler:=getvarinfo(hFile,iVar,varname2,varinfo);
fehler:=getvarhandle(hFile,@varname2,varhandle);
zwst1:=(ansistring(@varname2));
showmessage(zwst1);
end;
Ich bekomme leider die Variable „varname2“ nicht immer korrekt angezeigt. Normalerweise sollte ja der Inhalt einer Pointervariablen mit „^“ ausgelesen werden, aber damit bekomme ich nur eine Zugriffsverletzung. Mit der obigen Routine bekomme ich manchmal „varname2“ richtig angezeigt. „Manchmal“ heißt, je nachdem welche Datenbank ich öffne und einlese.
Ich vermute, es ist ein Konvertierungsproblem, aber warum bekomme ich manchmal etwas angezeigt und manchmal nicht. Wie schon gesagt, wenn ich „varname2“ einer weiteren DLL-Funktion übergebe, um numerische Datensätze auszulesen, bekomme ich alle Datensätze richtig ausgelesen und angezeigt. Nur der Zugriff auf „varname2“ selbst funktioniert nicht korrekt.
Hat jemand eine Idee?

DeddyH 2. Jan 2014 09:41

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Du musst auch Speicher für varname reservieren, den die DLL dann befüllt.

Testsieger 2. Jan 2014 09:44

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Ich habe schon "new(varname2)" eingebaut. Nützt leider auch nichts.
Trotzdem danke für den Tipp.

DeddyH 2. Jan 2014 09:52

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Bist Du sicher, dass das tatsächlich ein Ausgabeparameter ("out") ist? Normalerweise würde ich es ungefähr so versuchen:
Delphi-Quellcode:
var
  varname2: AnsiString;
begin
  SetLength(varname2, <Längenangabe>);
  fehler:=getvarinfo(hFile,iVar,PAnsiChar(varname2),varinfo);
  SetLength(varname2, StrLen(PAnsiChar(varname2)));

Testsieger 2. Jan 2014 09:57

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Es ist auf jeden Fall eine Ausgabe, sonst könnte die 2. Funktion ja nicht damit weiterarbeiten.
Ich probiere jetzt eben deinen Vorschlag aus. Irgendwo in diesem Bereich vermute ich auch meinen Fehler.

Danke schon mal...

Testsieger 2. Jan 2014 10:09

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Ich bekomme leider beim Compilieren die Fehlermeldung für den Funktionsaufruf mit pansichar(...), dass ein Konstantenobjekt nich als Var-Parameter übergeben werden kann.

DeddyH 2. Jan 2014 10:16

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Deshalb ja meine Frage nach dem out. Was passiert, wenn Du das weglässt?

Testsieger 2. Jan 2014 10:25

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Ich habe zu der DLL die Info zur Strukur und die sieht so aus:
Delphi-Quellcode:
int __stdcall GetVarInfo(
    const int hFile,
    const int iVar,
    char* varName,
    int* varType);
Ich brauche ja auch den Variablennamen. Manchmal (=je nach geöffneter Datenbank) bekomme kann ich ihn ja auch
richtig angezeigt, aber manchmal nur teilweise oder auch garnicht.

Warum bekomme ich eine Fehlermeldung im Programmablauf, wenn ich ansistring(@varname2) ändere in ansistring(varname2^). Das wäre doch eigentlich der korrekte Delphiuaufruf für einen Pointerinhalt.

DeddyH 2. Jan 2014 10:29

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Wo steht da etwas von Ausgabeparameter? Ich sehe da char* varName, also einen Zeiger auf ein Zeichen, was PAnsiChar/PWideChar entspricht. Lass also das out weg und versuch es noch einmal wie gezeigt, das sollte nach meinem Dafürhalten funktionieren.

Testsieger 2. Jan 2014 10:33

AW: String/Char-Pointer aus C# DLL korrekt auslesen
 
Habe ich mal ausprobiert, gibt leider einen "access violation" Fehler.
In der C#-Definition bedeutet "const", dass die Variable an die DLL übergeben werden muss und die
mit "*" versehenen Variablen kommen zurück, also out.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:47 Uhr.
Seite 1 von 3  1 23      

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