AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Delphi DLL String übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi DLL String übergeben

Ein Thema von DelTurbo · begonnen am 25. Mär 2024 · letzter Beitrag vom 28. Mär 2024
Antwort Antwort
Seite 2 von 3     12 3      
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.212 Beiträge
 
Delphi 2007 Architect
 
#11

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 10:46
Huhu,
es tut mir leid aber ich muss nochmal "Nerven". Ich hole mir einen String (die Antwort) folgendermaßen aus der DLL. Ist der String 2000 Lang klappt alles. Irgendwo bei 2500 liegt die grenze ab der ich dann komischerweise ein "Out of Memory" bekomme. Also 3000 Zeichen geht gar nicht. Ich versuche mal den Source wo es "knallt" hier zu Posten. Das ist ein kleines Testprogramm, dort kann ich die länge von dem String den haben möchte übergeben.

In der DLL mache ich das...
Delphi-Quellcode:
var
  Answer :WideString;

procedure GetTxt(A:PWideChar;L:Integer); cdecl;
var
  i :Integer;
begin
    Answer:='';
    for i:=0 to L-1 do begin
      Answer:=Answer+'A';
    end;
    Move(Answer,A^,Length(Answer));
end;
Im Programm das...
Delphi-Quellcode:
procedure TfMain.btnGetTxtClick(Sender: TObject);
var
  line :WideString;
begin
    SetLength(Antwort,StrToInt(edtTextLen.Text));
    GetTxt(@Antwort,StrToInt(edtTextLen.Text));
    SetString(line,PWideChar(@Antwort[0]),Length(Antwort)); // hier geht es in die Hose. Wie gesagt ab ca. 2500 Zeichen. Bei 2000 klappt es
end;
Ich habe gestern wie wild gegoogelt aber ich finde nichts. Es spielt auch keine Rolle ob die DLL mit Delphi 10.4 oder 2007 erstellt wurde.

Vielen Dank im voraus
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.993 Beiträge
 
Delphi 12 Athens
 
#12

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 10:54
0 ist definitiv falsch

PWideChar(@Antwort[1]) oder besser PWideChar(@Antwort[Low(string)]) (für die kurze Era wo das mal im Mobilen-Delphi ausprobiert wurde)
oder einfach nur direkt PWideChar(Antwort) , denn Ersteres knallt dir bei einem leeren String (Length=0) gnadenlos eine Exception entgegen.
https://docwiki.embarcadero.com/RADS...rings_(Delphi)



Für AnsiString's und UnicodeString/String müsste ShareMem verwendet werden, oder eben als PChar übergeben.

Wenn keine #0 im PChar/PWideChar oder PAnsiChar vorkommen, dann braucht man keine Länge einzeln zu übergeben.
MSDN-Library durchsuchenStrLen

Für WideString geht es geht es auch direkt, da es nicht den DelphiMM benutzt, sondern den MemoryManager vom OLE32
und intern ist es eigentlich ein Bei Google suchenBSTR, wofür automatisch die API um MSDN-Library durchsuchenSysAllocString/SysFreeString verwendet wird, welche auch C++ und Co. nutzen können.
Außerdem nutzt es somit auch eine Art von ShareMem (nur halt nicht das vom Delphi), weswegen es keine Probleme mit DLLs und COM-Interfaces gibt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Mär 2024 um 10:59 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.993 Beiträge
 
Delphi 12 Athens
 
#13

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 10:56
hier geht es in die Hose. Wie gesagt ab ca. 2500 Zeichen. Bei 2000 klappt es
Ich wüsste nicht, warum SetString eine Begrenzung haben sollte.

System._UStrFromPWCharLen für String/UnicodeString
System._WStrFromPWCharLen für WideString

[edit]
Arg, wer hat sich denn diesen totalen Schwachsinn ausgedacht?
Für WideString ist SetString komplett im A***

Echt mal, das einfach blind nach UnicodeString zu casten, ist grob fahrlässig ... hatte wohl auch wer mitbekommen und desswegen die Compilerwarnung via Pointer unterdrückt.
[/edit]

[edit2] Neee, das ist nur für Nicht-Windowse (iOS/ISX/Android/Linux), wo WideString heimlich ein UnicodeString ist.



So oder so, warum nimmst du nicht einfach Line := A; und lässt das mit dem Len weg?
Oder eben direkt WideString als Parameter nutzen.
procedure GetTxt(const A: WideString); cdecl;

Und wozu das cdecl? (möglicher Aufruf aus C++ oder so?)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Mär 2024 um 11:13 Uhr) Grund: ups
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.212 Beiträge
 
Delphi 2007 Architect
 
#14

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 11:17
Ich wollte nun sofort wenn ich aus der DLL wieder komme die Length(Antwort) ausgeben. Schon dabei scheppert es. Wenn ich mir den String Antwort im Debugger ansehe ist er meines Erachtens richtig. Auch eine Zusätzliche 0 am ende ändert nichts an der Sache.

Edit: @himitsu, Problem war am Anfang das die DLL unter Delphi 10.4 erstellt werden muss, ich aber mit Delphi 2007 arbeite. Da wurd ja ab Delphi 2009 etwas an den Strings geändert. "Rolf Frei" hat mich denn erstmal auf den richtigen Weg gebracht.
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!

Geändert von DelTurbo (28. Mär 2024 um 11:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.993 Beiträge
 
Delphi 12 Athens
 
#15

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 11:22
nochmal
Zitat:
0 ist definitiv falsch
ShortString: an Adresse 0 steht das LängenByte (ist intern ein Array[0..255] of AnsiChar),
und deswegen fangen auch neueren LongStrings (AnsiString und UnicodeString) seit 20 Jahren mit 1 an zu zählen.

Mit [0] schreibst zu in AdressOffest -1, also mitten in die Verwaltungsdaten, wo zufällig der Längen-Integer sich versteckt.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.212 Beiträge
 
Delphi 2007 Architect
 
#16

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 11:25
Das mit der 0 habe ich schon geändert. Oder ist auch das Move(Answer,A^,Length(Answer)); in der DLL Falsch? Wenn ja, wie komme ich auf A^ + 1? Also A^+1 geht nicht.
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.212 Beiträge
 
Delphi 2007 Architect
 
#17

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 11:31
Ups

Das im Programm habe ich falsch dargestellt. Das sieht so aus...

Delphi-Quellcode:
var
  Antwort :array of Char;

procedure TfMain.btnGetTxtClick(Sender: TObject);
var
  line :WideString;
begin
    SetLength(Antwort,StrToInt(edtTextLen.Text));
    GetTxt(@Antwort,StrToInt(edtTextLen.Text));
    SetString(line,PWideChar(@Antwort[1]),StrToInt(edtTextLen.Text)); //Length(Antwort));
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.993 Beiträge
 
Delphi 12 Athens
 
#18

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 16:03
dynamisches Array:

@Antwort ist ein Zeiger auf die Variable, nicht auf die Daten.
@Antwort[0] ist ein Zeiger auf das erste Char, bzw. auf alle Chars im Array.

Wie gesagt, mach doch einfach procedure GetTxt(var A: WideString; L: Integer); cdecl; und lass das ganze Rumgepointere sein.

Delphi-Quellcode:
procedure GetTxt(var A: WideString; L: Integer); cdecl;
var
  i :Integer;
begin
  ...
  A := Answer;
end;
Dann kann auch diese beschissene globale Variable weg.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Mär 2024 um 16:07 Uhr)
  Mit Zitat antworten Zitat
DelTurbo

Registriert seit: 12. Dez 2009
Ort: Eifel
1.212 Beiträge
 
Delphi 2007 Architect
 
#19

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 16:06
Hi,
danke dir habe es auf stdcall umgestellt. Läuft nun. Natürlich ohne Pointer
Alle meine Rechtschreibfehler sind Urheberrechtlich geschützt!!
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
646 Beiträge
 
Delphi 11 Alexandria
 
#20

AW: Delphi DLL String übergeben

  Alt 28. Mär 2024, 16:48
Du kannst ganz normal mit Strings arbeiten und benötigst kein Array of Char. Der Compiler nimmt dir da sehr viel Konvertierungsarbeit ab, wenn du es richtig machst. Ausserdem ist dir anscheinend nicht recht klar was der Unterschied von Unicode und Ansi ist. In Ansi (D2007) ist eine Zeichen (Char) ein Byte. Bei Unicode ist ein Zeichen (Char) 2 Byte. Du kannst also bei einem Speicher Movebefehl nicht einfach die Länge des String nehmen, da das dann zu wenig Speicher ist.

Move(Answer,A^,Length(Answer)); Das ist devinitv in der DLL falsch. Length(Answer) liefet dir die Anzahl Zeichen in Answer, aber du benötigst die Anzahl Bytes. Das muss daher so sein:
Move(Answer[1],A[0],Length(Answer) * SizeOf(Char)); Leider ist mir nicht mehr so recht klar, was du nun wo genau machst. Die DLL ist immer noch mit D10.4 geschrieben? Wenn ja darfst du da keine WideStrings nutzen sondern ganz normal mit String und Char arbeiten. WideString und PWideChar bezieht sich nur auf D2007.

D10.4 DLL:
Delphi-Quellcode:
var
  Answer :String;

procedure GetTxt(A:PChar;L:Integer); cdecl;
var
  i :Integer;
  
begin
    Answer:=StringOfChar('A', L);
    SetLength(A, L);
    Move(Answer[1],A[0],Length(Answer) * SizeOf(Char)); // benötigen hier Bytes nicht Zeichen!!!
end;
D2007 Anwendung:
Delphi-Quellcode:
var
  Antwort :String; // Dein D2007 kann in den TEdits, etc. eh kein Unicode nutzen, da macht es keinen Sinn mit WideString als Resultat.

procedure TfMain.btnGetTxtClick(Sender: TObject);
var
  wAntwort: Array of PWideChar;
begin
    SetLength(wAntwort,StrToInt(edtTextLen.Text));
    GetTxt(wAntwort[0],StrToInt(edtTextLen.Text));
    Antwort := String(WideString(wAntwort)); // Eventuell geht es auch nur mit String(wAntwort)

Geändert von Rolf Frei (28. Mär 2024 um 16:51 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 00:06 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