![]() |
String aus D5 DLL in Delphi 10.2 einslesen
Hallo
Ich habe folgendes Problem. Ich muss eine D5 DLL in ein D10.2 Projekt einbiden. An der D5 DLL kann ich nichts meh ändern. Die DLL übergibt einen String (böse :-) Ich habe das ganze mal auf folgende Minimalkostellation zusammengestaucht um das Problem zu zeigen. D5 DLL (Sharemem ist als erstes in der Uses Klausel)
Delphi-Quellcode:
in D10.2:
library Project_d5;
uses sharemem, SysUtils, Classes; function ExportString: string; export; forward; function ExportString: string; begin result := 'Hallo'; end; exports ExportString; end.
Delphi-Quellcode:
Beim Start wird zwar "Hallo" agezeigt, aber wenn die die Prozedur FormCreate verlassen wird, wirft das Programm eine Exception.
unit DLL_string;
interface uses sharemem, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; function ExportString: ansistring stcall; external 'xxx\Project_d5.dll'; var Form1: TForm1; implementation procedure TForm1.FormCreate(Sender: TObject); var a: shortstring; begin a := Exportstring; showmessage(a); end; Hat jemand eine Idee, wie ich Strings aus D5 DLLs sauber einlesen kann? PS. Falls das klappen sollte steht mir auch noch die Aufgabe bevor, StringLists aus D5 weier zu verarbeiten :-( Gruß Klaus |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Ist schon 20 jahre her, aber war da nicht was mit nach D5 wurde die Standard-Aufruf-Konvention für DLLs geändert, die Delphi nutzt, wenn nichts angegeben wurde ? Vllt. liegt es ja daran
|
AW: String aus D5 DLL in Delphi 10.2 einslesen
Wenn beim verlassen eine Exception kommt liegt es vermutlich am FreeMem bzw. RefCounter auf den String.
Probier mal einen PAnsiChar abzufragen und den String damit auszuwerten. In den 8 bytes vor der Referenz sollte sich die Länge und der Referenz Zähler befinden. |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Danke für die Antwort.
Ja, die Exception kommt beim Verlassen der Procedur. Aber wie soll ich das als pchar abfragen? Ich habe mal folgendes testweise gemacht: procedure TForm1.FormCreate(Sender: TObject); begin Exportstring; end; (Also nur die Prozedur aufrufen und das Ergebnis ignorieren), auch das wirft die Exception beim Verlassen der Prozedur. |
AW: String aus D5 DLL in Delphi 10.2 einslesen
ich meinte dies:
function ExportString: PAnsiChar stcall; external 'xxx\Project_d5.dll'; und mal sehen was Du mit dem Pointer machen kannst. Auf diese Weise wird ShareMem etc. nicht benötigt. |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Zitat:
gruss |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Soweit ich mich erinnere ging das mit den String-Rückgaben bei D5 ausschließlich in Verbindung mit Sharemem und/oder FastMM4. Daher würde ich orakeln, dass der Speichermanager von Tokio krachen geht. Evtl. hilft es, die DLL dynamisch (spät) zu laden und nach Gebrauch auch gleich wieder freizugeben.
|
AW: String aus D5 DLL in Delphi 10.2 einslesen
Hall,
laß unter D10 einfach mal das stdcall weg. |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Du deklarierst die Funktion mit einem Rückgabewert als AnsiString. In deiner Anwendung nutzt du aber einen ShortString. Nutze den selben StringtTyp in der Anwendung, also AnsiString. ShortString und AnsiString sind intern komplett anderes aufgebaut und ich kann mir gut vorstellen, dass es deswegen zu einer AV kommt.
|
AW: String aus D5 DLL in Delphi 10.2 einslesen
Hallo,
Zitat:
Sobald das falsche (denke ich) stdcall weg ist, 50:50 Chance ... Zitat:
![]() Notlösung wäre, den StringList.CommaString zu übergeben, also genau einen String. |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Wieso nicht einfach:
In der DLL: ExportString := StringList.Text in der Anwendung: StringList.Text := ExportString Damit lässt sich eine Stringlist mit der bestehenden Funktion ohne Probleme transferieren. Stcall wird doch sicher einen Compilerfehler bringen. Ich vermute das ist hier einfach ein Schreibfehler des OP im Forum. |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Wenn der Export aus der DLL nicht als StdCall deklariert wurde, sollte der Import es auch nicht sein.
Laut ![]() Normalerweise sollte man die aber in der DLL explizit angeben... Ansonsten: Mit Delphi 2007 wurde der Standard-Memory-Manager auf FastMM geändert. Früher wurde für ShareMem eine DLL (BORLNDMM.dll?) benötigt, die dann sowohl das Programm als auch die DLL zur Speicherverwaltung benutzt haben. Seit FastMM ist das nicht mehr notwendig. Ich frage mich gerade, ob das alte ShareMem noch kompatibel zum neuen ist. Vielleicht muss man ein Flag setzen? ![]() |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Zitat:
Die sauberte Lösung wäre (falls Du D5 noch verfügbar hast) für diese DLL eine Wrapper-Dll zu bauen, die wie eine Windows API-DLL alle exportierten Funktionen mit stdcall calling convention und ausschließlich unter Verwendung von API-kompatiblen Datentypen für Parameter und Rückgabewerte deklariert. Für Text wäre das PChar (= PAnsiChar in Tokyo). Du hast da sonst schwerwiegende Kompatibilitätsprobleme:
|
AW: String aus D5 DLL in Delphi 10.2 einslesen
Zitat:
Mein Pointer Ansatz geht leider nicht wie gedacht. Man kann die Funktion nicht einfach anders deklarieren. Das gibt sofort einen crash. Ich hatte mir das so gedacht:
Code:
Es geht, aber k.A. ob es hier ein Speicher loch gibt.
function ExportString: AnsiString; external '..\..\Project1.dll'; // oder stdcall
procedure TForm1.Button1Click(Sender: TObject); var s, s2 : AnsiString; pa : PAnsiChar; p : PInteger; begin s := ExportString; pa := PAnsiChar(s); p := PInteger(pa); dec(p); // Length SetString(s2, pa, p^); Edit1.Text := s2; dec(p); // RefCount p^ := p^ + 1; // Verhindere Free auf den String FreeMem(p); // String freigeben end; |
AW: String aus D5 DLL in Delphi 10.2 einslesen
Zitat:
Delphi-Quellcode:
d.h. der Aufruf übergibt die Addresse der Variable s an die Dll, die dann im Speicher der Hostanwendung herumpfuscht.
procedure ExportString(var S; string);
|
AW: String aus D5 DLL in Delphi 10.2 einslesen
Ich bin echt neugierig ob der Umweg über eine Wrapper-DLL funktioniert. Weil IMHO doch dann immer noch der Speichermanager der Hostanwendung am Werk ist. Oder denk ich da jetzt falsch und jede DLL verwaltet ihren Speicher selbst?
|
AW: String aus D5 DLL in Delphi 10.2 einslesen
Zitat:
Die Wrapper-DLL und die gewrappte sind beide mit D5 geschrieben und können daher (müssen sogar) ShareMem (die D5 Version) verwenden. Aber die Tokyo-Anwendung kann die Wrapper-DLL ohne Sharemem verwenden. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:51 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