Delphi-PRAXiS
Seite 9 von 12   « Erste     789 1011     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Unbegrenzt viele Nachkommastellen (https://www.delphipraxis.net/12974-unbegrenzt-viele-nachkommastellen.html)

Dano 23. Okt 2004 00:09

Re: Unbegrenzt viele Nachkommastellen
 
Hi Hagen,
ich bins nochmal ;)

nun habe ich mir frustriert ein bier aufgemacht weil ich an einer stelle hing die mir wirklich aussichtslos erschien (die parameterübergabe).... ich habe mich echt geärgert das der mir das self dazwischenmogelt und ich den "begin" der funktion wo er den refzähler des string erhöht nicht verhintern kann.... naja, wärend ich gemütlich das bier schlürfe hats klick gemacht.... ich mach die prozedur als asm, dann kann ich mit [ebp+$04] [ebp+$08] [ebp+$0c].... mir die richtigen werte bei stdcall selber von stack holen
man könnte auch register als aufrufkonvention nehmen, wäre das selbe in grün und schneller.... aber stack ist mir zum probieren lieber ;)
die refcounter von den string's muß ich zwar selber ändern, aber ist ja nicht schwer :)



*kopf auf den tisch hau*
warum bin ich da nicht gleich drauf gekommen

also hat sich das erstmal erledigt

mfg Dano

negaH 23. Okt 2004 03:20

Re: Unbegrenzt viele Nachkommastellen
 
Ich verstehe dich jetzt nicht so richtig.

Die Methode .SetName(const Name: String); solltest du prozedurale mal so betrachten:

Delphi-Quellcode:
procedure SetName(Self: PMyRecord; const Name: String); stdcall;
Self zeigt also auf deinen Record der ja sozusagen als TObject Ersatz dient. D.h. wenn du die VMT vin deinem Interface deklarierst so müsste diese so aussehen:

Delphi-Quellcode:
type
  PMyRecord = ^TMyRecord;
  TMyRecord = packed record
    VMT: PMyVMT;
    RefCount: Integer;
    Name: String;
  end;

  PMyVMT = ^TMyVMT;
  TMyVMT = packed record
    _QueryInterface: function(Self: PMyRecord; var Obj; const IID: TGUID): HResult; stdcall;
    _AddRef: function(Self: PMyRecord): HResult; sdtcall;
    _Release: function(Self: PMyRecord): HResult; sdtcall;
    GetName: function(Self: PMyRecord): String; stdcall;
    SetName: procedure(Self: PMyRecord; const Name: String); stdcall;
    GetRefCount: function(Self:PMyRecord): Integer; stdcall;
  end;

function MyQueryInterface(Self: PMyRecord; var Obj; const IID: TGUID): HResult; stdcall;
begin
  Result := S_ERROR;
end;

function MyAddref(Self: PMyRecord): HResult; stdcall;
begin
  InterlockedIncrement(Self.RefCount);
  Result := Self.RefCount;
end;

function MyRelease(Self: PMyRecord): HResult; stdcall;
begin
  InterlockedDecrement(Self.RefCount);
  Result := Self.RefCount;
  if Result = 0 then Dispose(Self);
end;

function MyGetName(Self: PMyRecord): String; stdcall;
begin
  Result := Self.Name;
end;

procedure MySetName(Self: PMyRecord; const Name: String); stdcall;
begin
  Self.Name := Name;
end;

function MyGetRefCount(Self: PMyRecord): Integer; stdcall;
begin
  Result := Self.RefCount;
end;

const
  VMT: TVMT = (
    _QueryInterface: MyQueryInterface;
    _AddRef: MyAddRef;
    _Release: MyRelease;
    GetName: MyGetName;
    SetName: MySetName;
    GetRefCount: MyGetRefCount;
);


function Alloc: IMyInterface;
var
  MyRecord: PMyRecord;
begin
  New(MyRecord);
  MyRecord.VMT := @VMT;
  Result := IInterface(MyRecord);
end;
Ohne Gewähr, ist alles aus dem Kopf ;)

Gruß Hagen

Dano 23. Okt 2004 16:50

Re: Unbegrenzt viele Nachkommastellen
 
Hi Hagen :)

hm... bei dir sieht das mal wieder so spielend einfach aus^^
mein problem war das ich nicht wußte wie ich das self mit in den funktionsaufruf einbauen soll
ich hatte das mit der VMT etwas anders gemacht

also das soll ein versuchs-interface zu einem string sein
hab mal bisel ordnung und struktur in alles gebracht.... aber im prinzip noch genauso wie vorher
Delphi-Quellcode:
 // Das String Interface
  IString = Interface(IInterface)
    function IS_GetString: String;
    procedure IS_SetString(AString: String);
    function IS_GetRefCount: Integer;
    property RefCount: Integer read IS_GetRefCount ;
    property AString: String read IS_GetString write IS_SetString;
  end;

  // Die VMT für das String Interface
  PStringVMT = ^TStringVMT;
  TStringVMT = packed record
    QueryInterface: Pointer;
    AddRef: Pointer;
    Release: Pointer;
    GetString: Pointer;
    SetString: Pointer;
    GetRefCount: Pointer;
  end;

  // Der Record für das String Interface
  PStringIntf = ^TStringIntf;
  TStringIntf = packed record
    StringVMT: PStringVMT;
    RefCount: Integer;
    AString: String;
  end;

procedure StringInit(var Dest: IString);
function IS_QueryInterface(Self: Pointer; const IID: TGUID; out Obj): HResult; stdcall;
function IS_AddRef(Self: Pointer): Integer; stdcall;
function IS_Release(Self: Pointer): Integer; stdcall;
function IS_GetString: String;
procedure IS_SetString(AString: String);
function IS_GetRefCount: Integer;

const
  // Die VMT für IString fertig Initialisiert
  ISGlobalVMT: TStringVMT = (
    QueryInterface: @IS_QueryInterface;
    AddRef: @IS_AddRef;
    Release: @IS_Release;
    GetString: @IS_GetString;
    SetString: @IS_SetString;
    GetRefCount: @IS_GetRefCount);

implementation

procedure IS_SetString(AString: String);
// stdcall: [ebp+$04] RücksprungAdresse
// [ebp+$08] Self(pointer auf interfacerecord)
// [ebp+$0c] String
// register: EDX String, EAX Self
// todo
// strings copy
// wenn refcount > 1 dann copy on demand
asm
  PUSH EAX              // self sichern
  LEA  EAX, [EAX+$08]   // Dest String nach EAX
  PUSH EDX              // Src String sichern
  MOV  EDX, ESP         // Zeiger auf Src
  CALL IS_LStrAsg       // procedure IS_LStrAsg(var dest; const source);


  usw.....
mein problem war das ich die funktionen so wie bei normalen objekten realisieren wollte.... und da gabs probleme mit dem self
im interface wird SetString ohne Self deklariert.... aber die eigentliche funktion muß mit self implementiert werden... aber ich habe beides gleich ohne self gehabt.... war irgendwie ein riesiger denkfehler von mir

naja, aber jetzt geht es einwandfrei *freu*
vielen dank Hagen :)

allerdings hatte ich mir mit dem string als test selber einen gemacht.... weil der compiler selber diverse stringumwandlungen einbaut und dabei unterscheidet woher der string kommt ob global... local... aus dynamischen resourcen(dll...) oder aus dem code,
und das müßte ich alles selber mit asm einbauen um die sicherheit zu geben das ein string nicht freigegeben wird der nicht freigegeben werden darf....

aber bei deiner variante kümmert sich der compiler wieder selber um alles ;)

mfg Dano

Dano 23. Okt 2004 19:21

Re: Unbegrenzt viele Nachkommastellen
 
so, und nun das fertige ergebniss :)
Delphi-Quellcode:
unit InterfaceString;

interface  

type
  // Das String Interface
  IString = Interface(IInterface)
    function IS_GetString: String;
    procedure IS_SetString(AString: String);
    function IS_GetRefCount: Integer;
    property RefCount: Integer read IS_GetRefCount ;
    property AString: String read IS_GetString write IS_SetString;
  end;

  // Die VMT für das String Interface
  PStringVMT = ^TStringVMT;
  TStringVMT = packed record
    QueryInterface: Pointer;
    AddRef: Pointer;
    Release: Pointer;
    GetString: Pointer;
    SetString: Pointer;
    GetRefCount: Pointer;
  end;

  // Der Record für das String Interface
  //PPStringIntf = ^PStringIntf;
  PStringIntf = ^TStringIntf;
  TStringIntf = packed record
    StringVMT: PStringVMT;
    RefCount: Integer;
    AString: String;
  end;


procedure StringInit(var Dest: IString);
function IS_QueryInterface(Self: PStringIntf; const IID: TGUID; out Obj): HResult; stdcall;
function IS_AddRef(Self: PStringIntf): Integer; stdcall;
function IS_Release(Self: PStringIntf): Integer; stdcall;
function IS_GetString(Self: PStringIntf): String;
procedure IS_SetString(Self: PStringIntf; AString: String);
function IS_GetRefCount(Self: PStringIntf): Integer;

function InterlockedIncrement(var I: Integer): Integer;
function InterlockedDecrement(var I: Integer): Integer;

const
  // Die VMT für IString fertig Initialisiert
  ISGlobalVMT: TStringVMT = (
    QueryInterface: @IS_QueryInterface;
    AddRef: @IS_AddRef;
    Release: @IS_Release;
    GetString: @IS_GetString;
    SetString: @IS_SetString;
    GetRefCount: @IS_GetRefCount);  

implementation

// Initialisiert das interface
procedure StringInit(var Dest: IString);
var
  NewIString: PStringIntf;
begin
  New(NewIString);
  NewIString^.StringVMT:=@ISGlobalVMT;
  NewIString^.RefCount:=0;
  NewIString^.AString:='Neues Interface';
  //SetLength(NewIString^.AString,$ffffff); //test ob IString freigegeben wird
  Dest:=IString(NewIString);
end;

function IS_QueryInterface(Self: PStringIntf; const IID: TGUID; out Obj): HResult; stdcall;
begin Result := HResult($80004002); end;

function IS_AddRef(Self: PStringIntf): Integer;
begin
  InterlockedIncrement(Self.RefCount);
  Result := Self.RefCount;
end;

// refcounter verringern und bei 0 den string freigeben
function IS_Release(Self: PStringIntf): Integer;
begin
  InterlockedDecrement(Self.RefCount);
  Result := Self.RefCount;
  if Result = 0 then begin
    Self.AString:='';
    Dispose(Self);
  end;
end;

function IS_GetString(Self: PStringIntf): String;
begin
  Result:=Self.AString;
end;

procedure IS_SetString(Self: PStringIntf; AString: String);
begin
  Self.AString:=AString;
end;

function IS_GetRefCount(Self: PStringIntf): Integer;
begin
  Result:=Self.RefCount;
end;

function InterlockedIncrement(var I: Integer): Integer;
asm
      MOV  EDX,1
      XCHG EAX,EDX
 LOCK XADD [EDX],EAX
      INC  EAX
end;

function InterlockedDecrement(var I: Integer): Integer;
asm
      MOV  EDX,-1
      XCHG EAX,EDX
 LOCK XADD [EDX],EAX
      DEC  EAX
end;

end.
nur schade das man bei
Delphi-Quellcode:
IIString.AString:='lalalalalalalalalala';
kein "Copy on Write Demand" einbauen kann


aber immerhin funzt es erstmal:)

mfg Dano

negaH 24. Okt 2004 18:36

Re: Unbegrenzt viele Nachkommastellen
 
Das stimmt, bei solchen Zugriffen kann das Interface nicht "Copy on Write Demand" machen. Deshalb auch meine Entscheidung alle DECMath Funktionen eben prozedural mit Overloading zu designen. In diesem Moment kann man VAR Parameter benutzen, ergo "Copy on Write Demand"

Allerdings ;) LongStrings in Delphi haben selber ein Referencecounting und Copy on Write Demand Feature.
Falls also deiner Interface nur in Delphi Sourcen verwendet werden sollen, so hast du auf Grund der LongStrings indirekt denoch ein Copy on Write Demand und Memory Sharing.

Gruß Hagen

Dano 24. Okt 2004 21:45

Re: Unbegrenzt viele Nachkommastellen
 
hi Hagen :)

das war ja nur ein test mit dem IString
die normalen strings sind natürlich um vieles besser

ich sags mal so:
nicht IString selber war mein ziel, sondern der weg zu IString und dem verstehen warum/wie es geht war das ziel
also der weg war das ziel.....
das ich strings als testopfer genommen habe war einfach eine entscheidung
irgendeinen sinn mußte ich der "selbsterkenntniss" ja geben ;)
einen richtigen sinn würde das erst mit objekten machen... dann kann man nie vergessen die freizugeben^^
oder dein waitcursor... der ist eigentlich auch genial :)
aber das beste sind natürlich die IInteger :)

ich habe dabei eine menge gelernt
ist eigentlich ein cooler trick mit den interfaces

jetzt wo ich weiß wie es geht kann man überlegen ob und wie man es verwendet ;)

mfg Dano

Nepos 17. Apr 2005 16:22

Re: Unbegrenzt viele Nachkommastellen
 
Ich weiß das dass thema schon länger zurückliegt aber ich wollte trotzdem eine frage wagen...
Ich bin in die kryptologie erst vor kürzerem eingestiegen. Seit dem fasinierte mich der RSA-Alogarithmus sehr. (fragt mich nicht warum...ich weiß es selber nicht^^)
Ich habe ein erfolgreiches programm geschreieben, doch wobald ich in eine höere potenz gehe (im rahmen z.b.: 7000^90)
zeigt er nur noch 0 an...es scheint mir delphi würde das nicht schaffen.
Ich benutze immoment den variablen typ extended.

Jetzt las ich hier in diesem thread über möglichkeiten der hohen stellen nach dem komma etc.
Ist es möglich dies in wenigen sätzen einem mathematisch nicht so weit entwickelten menschen wie mir^^ nahe zubringen was sinnvoll für mich ist zu tuhen.

Ich schäte negah's beiträge sehr!!! Doch verstehe ich höchstens 50%.

Meine frage ist es ist es möglich IInteger oä in mein programm o. Unit einzubinden das ich dieses wie eine andere von delphi's variablen einzubinden??
(Wie z.b.: var i:IInteger)

Oder muss man das ganz anders machen?

Ich freue mich über alle anregungen...

vielen dank für alle antworten im vorraus

NEPOS

negaH 18. Apr 2005 05:52

Re: Unbegrenzt viele Nachkommastellen
 
Ja das geht:

Delphi-Quellcode:

uses NInts, NMath;

interface

implementation

procedure RSA;
// RSA 1024 Bit verschlüsselung
var
  P,Q: IInteger;
  N: IInteger;   
  E,D: IInteger;
  U,Dp,Dq: IInteger;
  M,C: IInteger;  
  X,Y: IInteger;  
begin
// Schüssel Erzegung
  repeat
    NRnd(P, 512);
    NBit(P, 512 -2, True);
    NMakePrime(P, [1, 2]);
    repeat
      NRnd(Q, 512);
      NBit(Q, 512 -2, True);
      NMakePrime(Q, [1, 2]);
    until NCmp(P, Q) <> 0;
    if NCmp(P, Q) < 0 then NSwp(P, Q);   
    NMul(N, P, Q);
  until NSize(N) = 1024;

  NDec(P);
  NDec(Q);
  NLCM(U, P, Q);    
  repeat
    repeat
      NRnd(E, NLog2(NSize(N)) * 4);  
      NOdd(E, True);
    until NGCD1(E, P) and NGCD1(E, Q);
  until NInvMod(D, E, U) and (NSize(D) >= NSize(E)) and NGCD1(D, N);

  NMod(Dp, D, P);  
  NMod(Dq, D, Q);  
  NInc(P);
  NInc(Q);
  NInvMod(U, P, Q);

// privater und öffentlicher RSA Schlüssel sind nun fertig
// N,E ist der öffentliche Schlüssel
// N,D der private Schlüssel, wobei
// U,Dp,Dq,P,Q dazu gehören damit wir die Entschlüsselung um Faktor 4 beschleunigen können


// verschlüssele M den PlainText zu CipherText C = M^E mod N
  NSet(M, 'Unser Geheimnis', 256);
  NMod(M, N);         
  NPowMod(C, M, E, N);         

// entschlüssele C per Chinese Remainder Theorem ca. 4 mal schneller als normale Variante
  NPowMod(X, C, Dp, P);
  NPowMod(Y, C, Dq, Q);
  NCRT(Y, NInt([X, Y]), NInt([Dp, Dq]), NInt([U]));

// Y = M entschlüsselt
end.
Wie du siehst einfach per Uses einbinden und schwups ist RSA fertig.

gruß Hagen

Nepos 18. Apr 2005 16:54

Re: Unbegrenzt viele Nachkommastellen
 
Vielen dank Hagen :thumb: für deine Antwort! Ich verzweifel trotzdeines mitgelieferten quellcodes...denn irgendwie bin ich zu dumm den wuellcode einzubinden...
Ich habe ihn versucht in die Unit und in den "QUellcode" (Projekt -> Quellcode anzeigen) doch er zeigt beim copelieren eine reihe fehlermeldungen an... :cry:
Wie z.B. das er nicht mit IInteger etc zurecht kommt.
Bei der NMath sagt er "Deklaration erwartet, text ende gefunden"

Ich benutze D7 und habe Hagens DECMathD7 in die Lib kopiert...

Muss ich das irgendwie installiern?? Soweit ich das verstanden habe nicht...

ich hoffe ihr könnt mir helfen :lol:

Nepos

negaH 19. Apr 2005 06:16

Re: Unbegrenzt viele Nachkommastellen
 
Nichts in Lib kopieren, mit der Zeit würde sich da ja der ganze Rotz ansammeln.

Du entpackst die ZIP mit Ordnern und fertig ist alles installiert. Die im ZIP enthaltenen Dateiem im Ordner \LibInt\ sind nur die Header der Units vom DECMath. Sie enthalten also keine Implementation und können somit auch nicht direkt in dein Program eingebunden werden. Sie dienen dir als Dokumentation. (Edit: also auf KEINEN Fall dorthin ein Suchpfad legen, sonst versucht Delphi die teile wirklich zu komplieren)

Du musst auch garnichts einbinden ausser den Namen der Units in den Uses Klauseln. Dann musst du nur noch die Projektoptionen öffnen und den Pfad festlegen. Am besten schaust du dir mal ganz genau das DEMO Projekt an, auch dessen Projektoptionen. Dieses Projekt ist so eingestellt das es ohne zusätzliche Konfiguration vom Delphi denoch sofort compilierbar ist.

Für deine Projekte stehen dir nun zwei Möglichkeiten offen:

1.) du kompilierst ohne Packages und bindest somit die DCU vom DECMath in deine Anwendung ein. Dies übernimmt der Compiler/Linker für dich autom.

2.) du erzeugst dein Projekt mit Packages. Dazu müssen die Projektoptionen geändert werden und bei den benötigten Packages trägst du DECMath ein. Zu deiner EXE musst du dann natürlich auch die Packages mit installieren, sprich in diesem Falle die Datei DECMath.bpl.

Die von mir im Forum geposteten Versionen des DECMaths sind sogenannte binäre Distributationen, sie enthalten also nicht die vollständigen Quelltexte, sind aber voll funktionstüchtig und nicht eingeschränkt. Einzigste Lizenzbestimmung ist das du sie nicht weiter vertreiben darfst und nur in privaten oder rein akademischen Projekten verwenden kannst. Alles was darüber hinausgeht muß mit mir schriftlich abgeklärt werden (ich bin aber eine kulante und umgängliche Type :-)

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:47 Uhr.
Seite 9 von 12   « Erste     789 1011     Letzte »    

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