![]() |
Delphi-Version: 7
Dll schnittstelle ohne ShareMem
Hi,
ich möchte eine unabhängige Dll Schnittstelle implementieren. Für ein Delphi Programm sollen also Dlls mit nahezu jeder Sprache erstellt werden können. Dadurch fällt die Verwendung von ShareMem oder FastMM flach. Daher suche ich nun nach einer Lösung das ganze ohne Delphis hauseigenen Memorymanager umzusetzen. Dabei gibt es nun wenn ich es bisher richtig gesehen habe zwei Möglichkeiten. Entweder die Verwendung von Pchar bei der man sich selber um die allokation/deallokation kümmern muss, sowie um einen Mechanismus um die passenden Speichergrößen zu reservieren. Eine andere Möglichkeit ist die Verwendung von WideString was dann praktisch auf den COM Speichermanager hinaus läuft (OleAut32.dll). Erstmal hörte sich nun die Verwendung von WideString als eine ziemlich gute Idee an. Allerdings habe ich nun gelesen das es da seitens Delphi eventuell zu problemen kommen kann. Konkret möchte ich in meinem Programm folgende Funktion aus einer DLL die in beliebiger Sprache erstellt wurde einbinden:
Delphi-Quellcode:
Problem ist wohl das Delphi den Rückgabewert als In/Out implementiert hat und sich das mit den meisten anderen Sprachen beißt in denen der Rückgabewert einer Funktion als reiner Out Parameter implementiert wird. (Access violation)
function getParam(): WideString; stdcall;
Sehe ich es nun richtig das ich um dieses Problem generell komplett zu umgehen lediglich auf den Rückgabewert WideString verzichten muss und das Ergebnis über einen var Parameter zurückgeben ?
Delphi-Quellcode:
procedure getParam(var resuString: WideString); stdcall;
Gruß und Dank |
AW: Dll schnittstelle ohne ShareMem
Ja!
|
AW: Dll schnittstelle ohne ShareMem
Allerdings sollte es trotzdem eine Funktion sein, die dann einen entsprechend sinnvollen Rückgabewert zurückliefert (siehe Windows API).
Dann kann man auch so eine schöne Funktion bauen, die automatisch die Fehler wirft:
Delphi-Quellcode:
Natürlich liegt die Verantwortung dafür beim Konsument der DLL, es macht sich aber immer gut, wenn diese entsprechend gut strukturiert ist.
type
EFooApiException = class( Exception ); function GetFooApiErrorMessage( ErrorCode : ) : string; begin Result := ... end; procedure CheckFooApi( AResult : Integer ); begin if AResult <> 0 then raise EFooApiException.Create( GetFooApiErrorMessage( AResult ) ); end; |
AW: Dll schnittstelle ohne ShareMem
Wie ist das eigentlich mit dem Exception-Handling in anderen Sprachen?
Kommen die überhaupt mit den Delphi-Exceptions klar? (siehe CheckFooApi) Daß es eine Exceptions ist, werden die bestimmt mitbekommen, aber auch mit dem Typ "EFooApiException" und dessen Message? |
AW: Dll schnittstelle ohne ShareMem
Vielen Dank für die Antwort.
Eine weitere Frage kam mir noch auf. Mein Programm gibt ja sozusagen die Schnittstelle nach außen vor an die sich dann entwickler der Dll´s in beliebigen Sprachen halten müssen. Welche Datentypen soll/kann man verwenden um eine kompatiblität mit anderen Sprachen sicher zu stellen ? Momentan verwende ich WideString, Integer, Boolean Delphi WideString sollte ja in den C-Varianten BSTR sein ? Delphi Integer sollte ja in den C-Varianten int sein ? Bei boolean bin ich mir noch weniger sicher. Sollte man das Delphi boolean in seiner Programmimplementierung bei dem gewünschten Ziel verwenden ? Es gibt ja auch noch ByteBool, WordBool und LongBool. In C wäre boolean ja auch wieder int und sollte somit 32bit enstprechen. |
AW: Dll schnittstelle ohne ShareMem
Zitat:
|
AW: Dll schnittstelle ohne ShareMem
Delphi beherrscht verschiedene Aufrufkonventionen.
Aus
Delphi-Quellcode:
erzeugt der Delphi Compiler
function getParam(idx:Integer): WideString; safecall; // man beachte das safecall
Delphi-Quellcode:
Eine Exception innerhalb der Funktion bewirkt automatisch, dass das HResult <> S_OK und der ActiveX-Client die Exception-Message über bestimmte Interfaces (ISupportErrorInfo und IErrorInfo) abrufen kann.
function getParam(idx:Integer; out Result:WideString): HResult; stdcall;
Man darf allerdings nicht jede beliebige Exceptionklasse verwenden sondern nur EOleSysError oder EOleException und alles was davon noch abgeleitet ist. Umgekehrt wird bei jeder Funktion die mit der safecall-Konvention importiert wurde das HResult geprüft und ggf. eine Exception innerhalb der VCL mit der korrekten Exception-Message ausgelöst (diesmal ist die Delphi Anwendung der Client). Safecall ist also ein Mechanismus mit dem Exception-Informationen zwischen ActiveX Server und Client ausgetauscht werden. Funktionen, die eine Exceptioninformation über die Grenzen transportieren sollen müssen grundsätzlich ein HResult zurückgeben. Man kann aber jederzeit auf safecall verzichten und seine Funktionen nach der stdcall-Konvention exportieren. Da aber alle aktuellen ActiveX-Clients diesen "Trick" mit den Interfaces ISupportErrorInfo und IErrorInfo beherrschen und insbesondere Scriptsprachen darauf angewiesen sind würde ich empfehlen alle Funktionen mit safecall zu deklarieren und ausserdem sog. Dual Interfaces zu verwenden. Dann kann deine Bibliothek von Scriptsprachen (late binding über IDispatch) als auch über early binding angesprochen werden. PS: wenn du etwas spielen möchtest kannst du das "ActiveX Starterkit" runterladen. ![]() Es zeigt wie man eine Anwendung erstellt die von einem VB-Script festgesteuert wird. |
AW: Dll schnittstelle ohne ShareMem
Zitat:
Boolean würde ich nicht verwenden, sondern entweder LongBool (BOOL) oder ByteBool (bool), denn Boolean ist ein reiner Delphi-Typ (vielleicht noch in Borland C++ :stupid:) und die Konstanten (vorallem das True) haben ihre eigenen Werte/Definitionen. Wenn die anderen in ihren Sprachen das Selbe machen, wie ständig im Delphi gemacht wird, dann muß es ja knallen.
Delphi-Quellcode:
:stupid:
if myfunc() = True then
Vorallem die C-Sprachen und die WinAPI nutzen BOOL, welches intern ein INT (Integer) ist und oft mit 0 und -1 befüllt wird (Delphi-Boolean-True = 1) |
AW: Dll schnittstelle ohne ShareMem
Okay super das C / Windows-API BOOL entspricht dann dem LongBool oder dem WordBool ?
|
AW: Dll schnittstelle ohne ShareMem
![]() Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:57 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 by Thomas Breitkreuz