|
![]() |
|
Registriert seit: 11. Okt 2003 Ort: Elbflorenz 44.326 Beiträge Delphi 12 Athens |
#1
Es ist nicht Delphi, sondern Windows, bzw. das PE-Dateiformat (COFF).
Ja, statische DLL-Importe laufen über eine Import-Tabelle, welche aus vielen JMP+Adresse besteht, wo Delphi erstmal mit einem CALL rein springt und von dort dann erst zum eigentlichen DLL-Export. Und ja, wenn ich diese Adressen selbst verwalte (statt Methoden also MethodenZeiger verwende), könnte ich jeweils den einen JMP weglassen. Aber erstmal ist die Verwendung solcher Interfaces unintuitiver und ich habe eh noch Hoffnung auf bessere Lösungsansätze. * Direkt den originalen Quellcode neu kompilieren. * Oder zumindestens statt der .DCU an .OBJ-Dateien zu gelangen und statt der DLL alles direkt in die EXE zu linken. Zukünftig ist noch geplant die Einzel-Funktionen und Interfaces in Custom-Records zu verpacken. Dann würde ich da eventuell weitere Überlegungen in Betracht ziehen, dort nochmal etwas zu optimieren, bezüglich der JUMP/CALL. Mir ging es erstmal darum zusätzlich noch weitere/eigene JUMP/CALL dort reinzuschieben, und auch dafür noch tausende Wrapper-Funktionen schreiben zu müssen. (das hat sich zum Glück nun erledigt) Prinzipiell kompiliert jetzt erstmal alles, auch wenn ich an einigen Stellen noch rumfummeln muß. (aktuell sind dynamische Arrays und Strings dran) Delphi 7 DLL-Exports : ![]() Delphi 2006+ Imports : ![]() ![]()
Delphi-Quellcode:
procedure NSet(var A: IInteger; B: Integer); overload;
procedure NSet(var A: IInteger; B: Int64); overload; procedure NSet(var A: IInteger; B: Extended); overload; procedure NSet(var A: IInteger; const B: IInteger = nil; Abs: Boolean = False); overload; procedure NAdd(var A: IInteger; B: Integer); overload; procedure NAdd(var A: IInteger; const B: IInteger); overload; procedure NSub(var A: IInteger; B: Integer); overload; procedure NSub(var A: IInteger; const B: IInteger); overload; procedure NMul(var A: IInteger; B: Integer); overload; procedure NMul(var A: IInteger; B: Int64); overload; procedure NMul(var A: IInteger; const B: IInteger; C: Int64); overload; procedure NMul(var A: IInteger; const B: IInteger; C: Integer); overload; procedure NMul(var A: IInteger; const B: IInteger); overload; function NStr(const A: IInteger; Base: TBase = 0): RetString; overload; function NStr(const A: IInteger; const Format: TStrFormat): RetString; overload; Und die anderen Methoden haben fast alle den wichtigsten Parameter als Ersten, somit kann ich es als Methode in einen Record verschieben, und die Methode einfach als "external" deklarieren, womit dieser Parameter zum Self wird und direkt auf die DLL verweist. Standard-Oprtationen ala ADD, SUB und MUL, lassen sich dann zusätzlich auch schön in ClassOperator kapseln. Die Grundfunktionen ließen sich dann also wie beim normalen Integer benutzen. --- Es gab Anfangs sehr viele Fehler im Compilier, siehe ![]() Es handelte sich um folgene 3 Arten von Fehlern: overloaded functions with typeless parameters NInts.NSet(var A: IInteger; const B; Size: Integer; Bits: Integer) name 'NInts_NSet_IIBInIn', [Fehler] DECMath.dpr(66): Es existiert keine überladene Version von 'NSet' mit dieser Parameterliste. unnecessary overload and parameters not declared NECBuild name 'NECBuild_XXX', [Fehler] DECMath.dpr(625): Es existiert keine überladene Version von 'NECBuild' mit dieser Parameterliste. not overload, but still parameters declared NInts.NCat(var A: IInteger; const B: IIntegerArray; Bits: Integer) name 'NInts_NCat_IIIAIn', [Fehler] DECMath.dpr(109): ',' oder ';' erwartet, aber '(' gefunden [Fehler] DECMath.dpr(109): '=' erwartet, aber ';' gefunden [Fehler] DECMath.dpr(109): '=' erwartet, aber ')' gefunden [Fehler] DECMath.dpr(109): Undefinierter Bezeichner: 'name' [Fehler] DECMath.dpr(109): Inkompatible Typen: 'Integer' und 'String' [Fehler] DECMath.dpr(110): '=' erwartet, aber '.' gefunden ... Erstmal habe ich ein SharedMemory eingerichtet, womit es keine Probleme mit dynamischen Arrays und keine grundsätzlichen Probleme mit den DelphiStrings mehr geben sollte. Es gibt nun also die nur noch zwei Wrapper-Methoden, für die untypisierten Parameter. Ja, da könnte ich mit einem JMP in Assembler den einen Rücksprung des Wrappers einsparen, allerdings wäre dort der Aufwand höher im Assembler die richtige überladene Methode zu treffen. Dann gibt es eine Methode, wo ich aus einem Objekt ein Interface mache, durch eine zurätzliche Ableitung und cast des Result als Interface, wo sich nicht viel optimieren lässt. bzw. es ist bestimmt den Aufwand nicht wert. function Primes: TSmallPrimeSieve; wurde zu
Delphi-Quellcode:
(natürlich fehlt noch der Hook, um die Klassen auszutauschen, damit beim Create in der DCU der richtige Typ erzeugt wird)
type
ISmallPrimeSieve = interface ['{897D56D7-7514-4473-917E-3DEFCD9A54E3}'] function MinPrime: Cardinal; // min. Prime, allways 2 function MaxPrime: Cardinal; // max. possible Prime, dependend from Compiler Version function MinIndex: Cardinal; // min. Index, allways 1 function MaxIndex: Cardinal; // max. Index, see MaxPrime function Count(LowerBound, UpperBound: Cardinal): Cardinal; // compute Primecount beetwen Bounds function IndexOf(Value: Cardinal; LowerBound: Boolean{$IFDEF VER_D4H} = False{$ENDIF}): Cardinal; // give Primeindex of Value procedure LoadCache(const FileName: AnsiString); // load a Prime Cache procedure BuildCache(const FileName: AnsiString; Bound: Cardinal); // create and save a Cache function GetPrime(Index: Cardinal): Cardinal; property Prime[Index: Cardinal]: Cardinal read GetPrime; default; // return Prime with Index function CacheMaxPrime: Cardinal; // max. cached Prime function CacheMaxIndex: Cardinal; // max. cached Index of max. Prime // cached min. Values are allways equal to MinPrime, MinIndex end; TSmallPrimeSieveIntf = class(TSmallPrimeSieve, ISmallPrimeSieve) function MinPrime: Cardinal; function MaxPrime: Cardinal; function MinIndex: Cardinal; function MaxIndex: Cardinal; function GetPrime(Index: Cardinal): Cardinal; function CacheMaxPrime: Cardinal; function CacheMaxIndex: Cardinal; end; function PrimesIntf: ISmallPrimeSieve; begin Result := Primes as ISmallPrimeSieve; end; exports PrimesIntf name 'Prime_Primes', IsPrime name 'Prime_IsPrime'; Da sich seit Delphi 2009 die AnsiString intern verändert haben, muß ich dort unbedingt noch etwas anpassen. Jenes bezieht sich aber nur auf die wenigen function NStr(x: Interface): AnsiString; . Delphi 7:
Delphi-Quellcode:
Delphi 11.3
type
PStrRec = ^StrRec; StrRec = packed record refCnt: Longint; length: Longint; end;
Delphi-Quellcode:
Const-Parameter in die DLL rein, stellen nahezu keine Probleme dar,
type
// For System.pas internal use only. // Note, this type is duplicated in getmem.inc for diagnostic purposes. Keep in sync. PStrRec = ^StrRec; StrRec = packed record {$IF defined(CPU64BITS)} _Padding: Integer; // Make 16 byte align for payload.. {$ENDIF} codePage: Word; elemSize: Word; refCnt: Integer; length: Integer; end; da die zusätzlichen Felder für das alte Delphi praktisch unsichtbar/irrelevant sind. Aber als Funktion-Result sieht das anders aus. Da hätte ich die Wahl es via Wrapper auf WideString zu casten. Allerdings werde ich hier das ![]() und dort aus dem Delphi7-AnsiString in NeuesDelphi-AnsiString erzeugen. Denn das neue Delphi würde knallen, wenn es auf die nicht-vorhandenen Felder eines "alten" String zugreifen will -> BufferOverflow. Außerdem stimmt die Brechnung StringPointer->MemoryBlock nicht überein und es würde spätestens neuen Delphi beim Freigeben des String in LStrClr->FreeMem knallen. Es gibt aber noch ein paar weitere Hindernisse, mit anderen zu teilenden Dingen. Exception-Klassen und andere übergebene Klassen und Objekte, wie z.B. TStream. Siehe meine "TODO" bzw. Shared-Liste in ![]()
Ein Therapeut entspricht 1024 Gigapeut.
Geändert von himitsu (17. Sep 2023 um 12:54 Uhr) |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs 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
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |