![]() |
AW: DLL Exportiert ein Interface mit Strings...
Zitat:
|
AW: DLL Exportiert ein Interface mit Strings...
Die DLL muss mit den Methoden des IStream auskommen, kann aber damit den Inhalt der dahinter versteckten Klasse aus der Hauptanwendung verändern.
![]() |
AW: DLL Exportiert ein Interface mit Strings...
Zitat:
Ich muss an eine DLL 1-3 TStreams übergeben und diese an einen Procedure in der DLL weiterleiten... Was die Procedure damit macht kann ich nicht sagen. Mavarik |
AW: DLL Exportiert ein Interface mit Strings...
Wenn die Streams quasi "fertig" übergeben werden (gefüllt), dann pack die in einen IStream und in die DLL damit. In der DLL packst du die aus dem IStream in einen Stream und ab in die procedure.
Das wäre so die Holzhammer-Methode (sollte aber tun) Ansonsten bau dir einen IStream-Wrapper (abgeleitet von TStream) und übergib den in der DLL an die procedure |
AW: DLL Exportiert ein Interface mit Strings...
Zitat:
Was "kann" mein IStream-Wrapper "besser" bei der Übergabe? |
AW: DLL Exportiert ein Interface mit Strings...
Das Interface trennt den Code und Speichermanager an der Grenze von DLL und EXE,
also die enthaltene TStream-Instanz bleibt immer auf der Seite, wo das Interface erstellt wurde, selbst wenn das Interface in der anderen DLL/EXE verwendet wird. Klasseninstanzen lassen sich nunmal nicht im Bereich einer anderen RTTI (ohne Shared-RTTI aka BPLs) oder eines anderen Speichermanagers (ohne SharedMM) verwenden. Einfaches Beispiel: Du definierst in EXE und DLL eine Klasse. (egal, ob das aus ein und der selben Unit stammt, solange das jeweils einzeln einkompiliert wurde)
Delphi-Quellcode:
Jetzt greifst du in einem der beiden Kompilate nicht auf FStr zu, weswegen der Compiler das wegoptimiert.
type
TMyClass = class FStr: string; FInt: Integer; FXyz: Integer; end; Somit steht in dem einem Kompilat an Adresse X das FStr, während im anderem Kompilat an der selben Adresse das FInt steht, da das FStr dort ja weggelassen wurde. Greift man nun von der einen Seite auf das Objekt der anderen EXE/DLL zu, dann erwischt man z.B. FInt, anstatt FStr, welches dann natürlich ein falsches Ergebnis liefert. Das ist so, als wenn ich auf einer Straße ab der Hausnummer 6 alle Hausnummernschilder abschraube, die 6 weglasse und alles wieder um 1 versetzt anschraube. Wenn du jetzt aus einem Paralleluniversum kommst und wie gewohnt in Hausnummer 13 rein willst, dann stehst du bei uns im falschen Haus. :zwinker: (OK, der Vergleich hinkt ... eigentlich müsste ich das ganze Haus klauen und alle nachfolgenden Häuser entsprechend verschieben :angel:) [edit] Oder anders erklärt: - in einer der DLL/EXE wurde das FStr wegoptimiert - greift man nun auf FInt zu, dann liest man in Wirklichkeit das FXyz aus |
AW: DLL Exportiert ein Interface mit Strings...
Zitat:
Der DLL kannst du IStream übergeben, die macht daraus mit ihrem eigenen Speichermanager wieder TStream und ruft damit die Procedure der DCU auf. Das Beispiel weiter oben zeigt dabei alle Möglichkeiten auf, hier noch mal vereinfacht:
Delphi-Quellcode:
{dll-Funktion kapselt dcu}
function DllFunction(const Input, Output: IStream); var InputStream: TStream; OutputStream: TStream; begin InputStream := TOleStream.Create(Input); OutputStream := TOleStream.Create(Output); try {dcu-Funktion aufrufen} DcuFunction(InputStream, OutputStream); // <- erwartet TStream als Parameter finally InputStream.Free; OutputStream.Free; end; end; |
AW: DLL Exportiert ein Interface mit Strings...
Und hier mal komplett zusammengebaut:
|
AW: DLL Exportiert ein Interface mit Strings...
:thumb:
|
AW: DLL Exportiert ein Interface mit Strings...
HI,
ähnlichesn PROBLEM mit dll call von delphi aus: Bekomme nur Schrott in meiner Rückgabevariablen: Kann mir wer helfen was ich falsch mache? Calcsum ist ok, aber der String-Rückgabewert ist Schrott.
Delphi-Quellcode:
unit QMC_Unit;
interface uses ShareMem, Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} function calcsum(a: double; b: double):integer ; cdecl; external 'qmc_dll_Project1.dll'; procedure calcmain( var loesung: Pansichar) ; cdecl; external 'qmc_dll_Project1.dll'; procedure calcmaindummy( var loesung: PansiChar) ; cdecl; external 'qmc_dll_Project1.dll'; procedure TForm1.Button1Click(Sender: TObject); var loesung: PAnsiChar; begin ShowMessage(inttostr(calcsum(1,2))); calcmaindummy(loesung); ShowMessage(String(loesung)); end; end.
Delphi-Quellcode:
// Wichtiger Hinweis zur DLL-Speicherverwaltung, wenn Ihre DLL die statische
// Version der Laufzeitbibliothek verwendet: // // Wenn Ihre DLL Funktionen exportiert, die String-Objekte (oder Strukturen/Klassen // mit verschachtelten Strings) als Parameter oder Funktionsergebnisse übergeben, // müssen Sie die Bibliothek MEMMGR.LIB dem DLL-Projekt und allen anderen Projekten, // die die DLL verwenden, hinzufügen. Außerdem müssen Sie die MEMMGR.LIB verwenden, // wenn andere Projekte, die die DLL einsetzen, Neu- oder Löschen-Operationen für nicht // von TObject abgeleitete Klassen durchführen, die aus der DLL exportiert // wurden. Das Hinzufügen von MEMMGR.LIB zu Ihrem Projekt ändert die DLL und ihre aufrufenden // EXE-Dateien, damit diese BORLNDMM.DLL als Speicherverwaltung verwenden. In diesen Fällen // muss die Datei BORLNDMM.DLL zusammen mit Ihrer DLL weitergegeben werden. // // Übergeben Sie String-Informationen mit "char *" oder ShortString-Parametern, // um die Verwendung von BORLNDMM.DLL zu vermeiden. // // Wenn Ihre DLL die dynamische Version der RTL verwendet, müssen Sie MEMMGR.LIB // nicht explizit hinzufügen, weil dies implizit ausgeführt wird. #pragma argsused extern int __declspec(dllexport) __stdcall calcsum(double a, double b){ return a + b; } extern void __declspec(dllexport) __stdcall calcmaindummy(char* loesungdummy) { loesungdummy = "TESTENDE:2ndLine"; //resultbuff; } int _libmain(unsigned long reason) { return 1; } |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:04 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