IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants VCL Delphi Discussion :

Callback en « C » et Delphi Events


Sujet :

Composants VCL Delphi

  1. #1
    Membre régulier Avatar de saidus
    Homme Profil pro
    Inscrit en
    Octobre 2004
    Messages
    165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46

    Informations forums :
    Inscription : Octobre 2004
    Messages : 165
    Points : 89
    Points
    89
    Par défaut Callback en « C » et Delphi Events
    Bonjour*!!
    J’ai écris une DLL en C qui export quelques fonctions qui prennent comme
    paramètre un pointeur sur une structure ( struct *).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    PEXPORT int  SommeFunc( struct * PStr)*;
    La structure en elle-même comporte deux pointeurs sur fonctions (pour le Callback)
    Jusque la tout va bien et les test vont bien ( en C et en Delphi ).
    Voici l’interpretation en Delphi du fichier .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    const
      bsLib2 = 'wgetfire2.dll' ;
    type
      bsSplitAll = function (total : Double; chunk : integer )	: Integer ; cdecl;
      bsProgress = function (ptr: Pointer ;dltotal, dlNow, dlspeed : Double ; Handle: Integer): Integer ; cdecl;
     
    (* typedef struct _bsHttpFile
    {
    	bStr		URL		;	// url
    	UInt        Port	;	// port  80
    	bStr		User	;
    	bStr		Pass
        bStr		Local	;	// local file name 
        UInt        threadCount;// num of threads (not used )	
    	UInt		Chunk	;	// chunk for splitting
        //Callback Functions      
        bsSplitAll	Spt		;	// splitting files 
    	bsProgress  WPrg	; 	// my progress to manage Progress Bars
    } bsHttpFile, *PbsHttpFile; *)
      PbsHttpFile = ^TbsHttpFile ;
      TbsHttpFile = record
        URL   : PChar ;
        Port  : Word  ;
        User  : PChar ;
        Pass  : PChar ;
        Local : PChar ;
        Threads: Word ;
        Chunk : Longint ;
        Spt   : bsSplitAll;
        WPrg  : bsProgress;
      end;
    // fonctions 
    function bsGetFileFromHttp6 (const htp: PbsHttpFile ) : integer; cdecl; external bsLib2 name 'bsGetFileFromHttp6';
    function bsGetFileFromHttp8 (const htp: PbsHttpFile ) : integer; cdecl; external bsLib2;
    Le problème se manifeste lorsque je crée un composant qui encapsuler cette DLL au nivaux
    du <B>passage d’un événement dans le Callback</B> { récupérer les valeurs du Callback dans l’événement déclanché }
    Voici le code pour plus de clarté ..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
     
     
    interface
      TDownloadProgress = procedure ( Sender: TObject; dltotal, dlNow: Integer ;
              dlspeed: Double; Handle: Integer) of object;
     
     
      TbsCurlGrabber = class(TComponent)
      private
        //... Others Fields 
    	FOnDwProgress: TDownloadProgress;
    	//...
      protected
        procedure TriggerDwProgress(Sender: TObject; dltotal, dlNow: Integer ;
              dlspeed: Double; Handle: Integer);
    	// .....
      public
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
        function bsGetFileFromHttp: Integer;
      published
        property OnDwProgress: TDownloadProgress read FOnDwProgress write  SetOnDwProgress;
    	// ...
      end;
     
    implementation
    function DoProgress(ptr: Pointer; dltotal, dlNow, dlspeed: Double; Handle:
        Integer): Integer; cdecl;
    begin
    //   with TbsCurlGrabber(ptr) do
    //   begin
    //     {TriggerDownloadProgress(TObject(ptr),LongInt(Round(dltotal)),LongInt(Round(dlNow)),dlspeed,Handle);}
    //     TriggerDwProgress(TObject(ptr),LongInt(Round(dltotal)),LongInt(Round(dlNow)),dlspeed,Handle);
    //   end;    // with // ne marche pas 
      with TbsCurlGrabber(ptr) do
      begin
        if (@FOnDwProgress <> nil) then begin // if Assigned(FOnDwProgress) aussi ne marche pas 
          FOnDwProgress(TbsCurlGrabber(ptr),LongInt(Round(dltotal)), LongInt(Round(dlNow)),dlspeed,Handle);
          ShowMessage('Tester for ME');
        end;
      end;    // with et ne marche pas aussi 
      result := 0; 
    end;
     
    function TbsCurlGrabber.bsGetFileFromHttp: Integer;
    begin
     
      with fbsHttpFile do
      begin
        URL   :=  PChar(FURL) ;
        Port  :=  FPort ;
        Chunk :=  FChunk ;
        Local :=  PChar(FOutFile) ;
        Spt := nil ;
        WPrg := @DoProgress ;
      end;    // with
     
      case FThreads of    //
        thD6 : Result := bsGetFileFromHttp6 (@fbsHttpFile);
        thD8 : Result := bsGetFileFromHttp8 (@fbsHttpFile);  
      else
        Result := 0
      end;
    enfin j'ai essayer tout les moyens ..
    déclanche l'evenement via le procedure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
        procedure TriggerDwProgress(Sender: TObject; dltotal, dlNow: Integer ;
              dlspeed: Double; Handle: Integer);
    puis passer cetter deniere dans le Callback mais rien ne marche ..
    Sincerement je ne sais quoi faire
    MERCI POUR VOTRE AIDE MESSIEURS
    Dhukmucmur Vernedh

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    with TbsCurlGrabber(ptr) do
    ça ne serait pas plutôt ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    with PbsHttpFile(ptr)^ do
    Te ne transmets jamais Self à ta DLL, donc impossible qu'elle puisse te le renvoyer ... tu te mélanges les pinceaux, en plus c'est assez fouilli !

    Pour retrouver l'instance qui lancé la DLL depuis la CallBack, cela ne va pas être pratique hors un singleton ou une HashList ou tu associe pour un PbsHttpFile une instance de TbsCurlGrabber
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Ah ah, oui, ton problème est assez classique, mais tu l'exprimes mal.

    Voici le problème redéfini : tu veux transmettre une méthode (procédure d'un objet) à un call-back qui doit recevoir une routine (procédure hors objet).

    Ceci n'est, bien entendu, pas possible, puisqu'un méthode c'est une routine plus un objet. Tu ne peux pas mettre deux informations dans une seule, et espérer que le code qui appelle ton call-back gèrera correctement le Self implicite des objets.

    Cependant, ceci peut être contourné, en générant une routine qui pointe sur ta méthode à l'exécution.

    Si comprendre le fonctionnement ne t'intéresse pas, focalise-toi sur les section suivante :
    VI. Comment utiliser les routines que nous allons développer ?
    et le code complet est dans l'unité ScDelphiLanguage.pas.

    La méthode qui t'intéresse est MakeProcOfCDeclMethod, bien entendu.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  4. #4
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    ton code devrait plutôt ressembler à cela :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    unit WGetFire2;
     
    interface
     
     
    type
      WGFCallBackSplitAll = function(aPtr: Pointer; aTotal: Double; aChunk: integer): Integer; cdecl;
      WGFCallBackProgress = function(aPtr: Pointer; aDlTotal, aDlNow, aDlSpeed: Double; aHandle: Integer): Integer; cdecl;
     
     
    const
      WGFCallBackStopNeeded = -1;
      WGFCallBackContinue   = 0;
      WGFCallBackError      = 1;
      WGFCallBackComplete   = 2;
     
      WGFThreadD6        = 0;
      WGFThreadD8        = 1;
     
      WGFPortDefault     = 80;
      WGFPortAlternative = 8080;
     
      WGFChunkDefault    = 0;
     
     
    type
      PWGFHttpFile = ^TWGFHttpFile;
      TWGFHttpFile = packed record
        URL     : PChar;               // url
        Port    : Word;                // port 80
        User    : PChar;               // user login
        Pass    : PChar;               // user password
        Local   : PChar;               // local file name
        Threads : Word;                // number of thread (not used 0)
        Chunk   : Longint;             // chunck for splitting
        Spt     : WGFCallBackSplitAll; // callback splitting files
        WPrg    : WGFCallBackProgress; // callback download progress
      end;
     
     
    function WGFGetFileFromHttp6(const aPHttpFile: PWGFHttpFile): integer cdecl;
    function WGFGetFileFromHttp8(const aPHttpFile: PWGFHttpFile): integer cdecl;
     
    implementation
     
    const
      WGFLib2 = 'WGetFire2.dll';
     
    function WGFGetFileFromHttp6; external WGFLib2 name 'bsGetFileFromHttp6';
    function WGFGetFileFromHttp8; external WGFLib2 name 'bsGetFileFromHttp8';
     
    end.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    unit WGetFireClass;
     
    interface
     
    uses
      Windows,
      SysUtils,
      Classes,
      Controls,
      Dialogs,
      WGetFire2;
     
     
     
    type
      TWGFThread = (
        wtD6 = WGFThreadD6,
        wtD8 = WGFThreadD8
      );
     
      TWGFDlProgressEvent = procedure(Sender: TObject; aDlTotal, aDlNow, aDlSpeed: Double;
                                      aHandle: integer; var aReturn: Integer) of object;
      TWGFDlSplitEvent    = procedure(Sender: TObject; aTotal: double;
                                      aChunck: integer; var aReturn: integer) of object;
     
      TWGFUrlGrabber = class(TComponent)
      private
        ffLock    : boolean;
        ffFcStp   : boolean;
     
        ffURL     : string;
        ffUser    : string;
        ffPass    : string;
        ffLocal   : string;
        ffThread  : TWGFThread;
     
        fHttpFile    : TWGFHttpFile;
     
        fOnDlProgress: TWGFDlProgressEvent;
        fOnDlSplit   : TWGFDlSplitEvent;
        fOnLock      : TNotifyEvent;
        fOnUnlock    : TNotifyEvent;
     
        function GetChunk: LongInt;
        function GetPort: Word;
        procedure SetChunk(const Value: LongInt);
        procedure SetLocal(const Value: string);
        procedure SetPass(const Value: string);
        procedure SetPort(const Value: Word);
        procedure SetUrl(const Value: string);
        procedure SetUser(const Value: string);
        function GetThreads: TWGFThread;
        procedure SetThreads(const Value: TWGFThread);
     
      protected
        procedure DoLock;   // component is locked on Execute starting
        procedure DoUnlock; // component is unlocked on Execute ending
     
      published
        property URL     : string     read ffUrl      write SetUrl;
        property Port    : Word       read GetPort    write SetPort    default WGFPortDefault;
        property User    : string     read ffUser     write SetUser;
        property Pass    : string     read ffPass     write SetPass;
        property Local   : string     read ffLocal    write SetLocal;
        property Threads : TWGFThread read GetThreads write SetThreads default wtD6;
        property Chunk   : LongInt    read GetChunk   write SetChunk   default WGFChunkDefault;
     
        property Locked  : boolean    read ffLock;
     
        property OnDownloadProgress : TWGFDlProgressEvent read fOnDlProgress write fOnDlProgress;
        property OnDownloadSplit    : TWGFDlSplitEvent    read fOnDlSplit    write fOnDlSplit;
     
        property OnLock             : TNotifyEvent        read fOnLock       write fOnLock;
        property OnUnlock           : TNotifyEvent        read fOnUnlock     write fOnUnlock;
     
      public
        function Execute: Integer;
        function ForceStop: Integer;
     
        constructor Create(AOwner: TComponent); override;
        destructor Destroy; override;
     
      end;
     
    implementation
     
     
    { TWGFUrlGrabber }
     
    function CallBackDlProgress(aPtr: Pointer; aDlTotal, aDlNow, aDlSpeed: Double; aHandle: Integer): Integer; cdecl;
    var UG : TWGFUrlGrabber;
    begin
      UG := TWGFUrlGrabber(aPtr);
     
      if UG.ffFcStp then
        result := WGFCallBackStopNeeded
      else
        result := WGFCallBackContinue;
     
      if Assigned(UG.fOnDlProgress) then
        UG.fOnDlProgress(UG, aDlTotal, aDlNow, aDlSpeed, aHandle, result);
     
      if UG.ffFcStp then
        result := result or WGFCallBackStopNeeded;
    end;
     
    function CallBackSplitAll(aPtr: Pointer; aTotal: Double; aChunck: integer): Integer; cdecl;
    var UG : TWGFUrlGrabber;
    begin
      UG := TWGFUrlGrabber(aPtr);
     
      if UG.ffFcStp then
        result := WGFCallBackStopNeeded
      else
        result := WGFCallBackContinue;
     
      if Assigned(UG.fOnDlSplit) then
        UG.fOnDlSplit(UG, aTotal, aChunck, result);
     
      if UG.ffFcStp then
        result := result or WGFCallBackStopNeeded;
    end;
     
    constructor TWGFUrlGrabber.Create(AOwner: TComponent);
    begin
      inherited;
      ffLock    := false;
      ffFcStp   := false;
     
      ffURL     := '';
      ffUser    := '';
      ffPass    := '';
      ffLocal   := '';
      ffThread  := wtD6;
     
      fHttpFile.URL     := PChar(ffURL);
      fHttpFile.User    := PChar(ffUser);
      fHttpFile.Pass    := PChar(ffPass);
      fHttpFile.Local   := PChar(ffLocal);
      fHttpFile.Port    := WGFPortDefault;
      fHttpFile.Threads := WGFThreadD6;
      fHttpFile.Chunk   := WGFChunkDefault;
      fHttpFile.Spt     := CallBackSplitAll;
      fHttpFile.WPrg    := CallBackDlProgress;
    end;
     
    destructor TWGFUrlGrabber.Destroy;
    begin
      if not ffLock then
      begin
        MessageDlg('Url grabber is running, cannot be destroyed at this time.', mtWarning, [mbOk], 0);
        exit;
      end;
     
      inherited;
    end;
     
    procedure TWGFUrlGrabber.DoLock;
    begin
      if not ffLock then
      begin
        if assigned(fOnLock) then
          fOnLock(Self);
        ffLock := true;
      end;
    end;
     
    procedure TWGFUrlGrabber.DoUnlock;
    begin
      if ffLock then
      begin
        ffLock := false;
        if assigned(fOnUnlock) then
          fOnUnlock(Self);
      end;
    end;
     
    function TWGFUrlGrabber.Execute: integer;
    begin
      result := -1;
     
      if ffLock then
        exit;
     
      DoLock;
      try
     
        { others checks here }
     
        case fHttpFile.Threads of
          WGFThreadD6 : result := WGFGetFileFromHttp6(@fHttpFile);
          WGFThreadD8 : result := WGFGetFileFromHttp8(@fHttpFile);
        end;
      finally
        DoUnlock;
        ffFcStp := false;
      end;
    end;
     
    function TWGFUrlGrabber.ForceStop: Integer;
    begin
      ffFcStp := true;
    end;
     
    function TWGFUrlGrabber.GetChunk: LongInt;
    begin
      result := fHttpFile.Chunk;
    end;
     
    function TWGFUrlGrabber.GetPort: Word;
    begin
      result := fHttpFile.Port;
    end;
     
     
    function TWGFUrlGrabber.GetThreads: TWGFThread;
    begin
      case fHttpFile.Threads of
        WGFThreadD6      : result := wtD6;
        WGFThreadD8      : result := wtD8;
      end;
    end;
     
    procedure TWGFUrlGrabber.SetChunk(const Value: LongInt);
    begin
      if (fHttpFile.Chunk <> Value) and not ffLock then
      begin
        fHttpFile.Chunk := Value;
     
        { others traitments here }
     
      end;
    end;
     
    procedure TWGFUrlGrabber.SetLocal(const Value: string);
    begin
      if (ffLocal <> Value) and not ffLock then
      begin
        ffLocal := Value;
     
        { others traitments here }
     
      end;
    end;
     
    procedure TWGFUrlGrabber.SetPass(const Value: string);
    begin
      if (ffPass <> Value) and not ffLock then
      begin
        ffPass := Value;
     
        { others traitments here }
     
      end;
    end;
     
    procedure TWGFUrlGrabber.SetPort(const Value: Word);
    begin
      if (fHttpFile.Port <> Value) and not ffLock then
      begin
        fHttpFile.Port := Value;
     
        { others traitments here }
     
      end;
    end;
     
    procedure TWGFUrlGrabber.SetThreads(const Value: TWGFThread);
    begin
      if (ffThread <> Value) and not ffLock then
      begin
        ffThread := value;
        case ffThread of
          wtD6      : fHttpFile.Threads := WGFThreadD6;
          wtD8      : fHttpFile.Threads := WGFThreadD8;
        end;
     
        { others traitments here }
     
      end;
    end;
     
    procedure TWGFUrlGrabber.SetUrl(const Value: string);
    begin
      if (ffUrl <> Value) and not ffLock then
      begin
        ffUrl := Value;
     
        { others traitments here }
     
      end;
    end;
     
    procedure TWGFUrlGrabber.SetUser(const Value: string);
    begin
      if (ffUser <> Value) and not ffLock then
      begin
        ffUser := Value;
     
        { others traitments here }
     
      end;
    end;
     
    end.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Dr. Who, ton code est vraiement plus beau, par contre, pour le code suivant, tu peux m'expliquer ?
    Je pensais que aPtr serait @fHttpFile puisque c'est ce que l'on passe à la DLL et non Self ...
    Et donc on en revient à ce que propose SJRD d'utiliser un méthode d'objet pour le CallBack même si a mon avis, faut y aller doucement, saidus n'est toujours pas venu nous répondre !
    Ou alors modifier la DLL C++ puisque que Saidus en est l'auteur pour ajouter un paramètre "Parent: Pointer" (qui serait Self)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function CallBackSplitAll(aPtr: Pointer; aTotal: Double; aChunck: integer): Integer; cdecl;
    var UG : TWGFUrlGrabber;
    begin
      UG := TWGFUrlGrabber(aPtr);
     
      if UG.ffFcStp then
    ...
    s'écrit plus simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function CallBackSplitAll(aPtr: Pointer; aTotal: Double; aChunck: integer): Integer; cdecl;
    var  
      UG : TWGFUrlGrabber absolute aPtr;
    begin
      if UG.ffFcStp then
    ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  6. #6
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    hahaha mais oui :

    dans le wrapper :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
      TWGFHttpFile = packed record
        URL     : PChar;               // url
        Port    : Word;                // port 80
        User    : PChar;               // user login
        Pass    : PChar;               // user password
        Local   : PChar;               // local file name
        Threads : Word;                // number of thread (not used 0)
        Chunk   : Longint;             // chunck for splitting
        Spt     : WGFCallBackSplitAll; // callback splitting files
        WPrg    : WGFCallBackProgress; // callback download progress
        Caller  : pointer; // object for callback aPtr parameters
      end;
    et dans la classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    constructor TWGFUrlGrabber.Create(AOwner: TComponent);
    begin
      inherited;
      ffLock    := false;
      ffFcStp   := false;
     
      ffURL     := '';
      ffUser    := '';
      ffPass    := '';
      ffLocal   := '';
      ffThread  := wtD6;
     
      fHttpFile.URL     := PChar(ffURL);
      fHttpFile.User    := PChar(ffUser);
      fHttpFile.Pass    := PChar(ffPass);
      fHttpFile.Local   := PChar(ffLocal);
      fHttpFile.Port    := WGFPortDefault;
      fHttpFile.Threads := WGFThreadD6;
      fHttpFile.Chunk   := WGFChunkDefault;
      fHttpFile.Spt     := CallBackSplitAll;
      fHttpFile.WPrg    := CallBackDlProgress;
      fHttpFile.Caller  := Pointer(Self);
    end;

    par contre le Absolute, faut oublier, ça rend les méthode plus lente.

    exemple de code qui le démontre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    function aRGB(R, G, B: byte): integer;
    var
      rRGB : array[0..3] of byte absolute result;
    begin
      rRGB[0] := R;
      rRGB[1] := G;
      rRGB[2] := B;
      rRGB[3] := 0;
    end;
     
    function xRGB(R, G, B: byte): integer;
      type
        PRGB = ^TRGB;
        TRGB = packed array[0..3] of byte;
    var
      P : PRGB;
    begin
      P := PRGB(result);
      P[0] := R;
      P[1] := G;
      P[2] := B;
      P[3] := 0;
    end;
     
    function wRGB(R, G, B: byte): integer;
    begin
      result := R or (G shl 8) or (B shl 16);
    end;
     
    function mRGB(R, G, B: byte): integer;
    asm
      mov ah, B;
      shl eax, $8;
      mov ah, G;
      mov al, R;
    end;
    pour 10 000 000 d'appels :
    aRGB : 525 497 cycles pour 141ms en moyenne
    xRGB : 201 937 cycles pour 62ms en moyenne
    wRGB : 165 956 cycles pour 47ms en moyenne
    mRGB : 145 520 cycles pour 31ms en moyenne

    si dans xRGB on transtype directement en TRGB on obtient les mêmes performances (a peu prés) que la fonction aRGB.
    même avec une déclaration de deux types à l'intérieur de la fonction xRGB et le transtypage via le type PRGB la rend plus de deux fois plus performante que la version avec absolute.
    sortir la déclaration de type de xRGB la rend un chouilla plus performante.

    on remarque également que mRGB et wRGB sont les fonctions les plus rapide,
    notamment mRGB en pur assembleur qui utilise 3 mov et 1 seul shl (contrairement à wRGB qui utilise 2 shl, 2 or et 2 mov).


    donc absolute = à déprécié.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  7. #7
    Membre régulier Avatar de saidus
    Homme Profil pro
    Inscrit en
    Octobre 2004
    Messages
    165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46

    Informations forums :
    Inscription : Octobre 2004
    Messages : 165
    Points : 89
    Points
    89
    Par défaut
    Merci MEssaieurs pour l'aide que vous m'appportez..
    enfaite j'aissai de creer une DLL wrapper pour la libcurl afin d'encapsuler juste ce qu'il me faut pour creer un downloader thridee {un peu comme idm}
    je vous tiendrai au courant des events
    MErci encore ... je vais essayer le code ce soir
    A+++
    Dhukmucmur Vernedh

  8. #8
    Membre régulier Avatar de saidus
    Homme Profil pro
    Inscrit en
    Octobre 2004
    Messages
    165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46

    Informations forums :
    Inscription : Octobre 2004
    Messages : 165
    Points : 89
    Points
    89
    Par défaut
    Bonjour !!!
    Ci joint messieurs une archive curlgrabber_error.zip (rar)
    qui contient la dll et le .h avec une translation en delphi
    du .h , puis un exemple de demonstration .
    je vous informe que j'ai fait toutes les modifs dont vous
    m'avez conseiller mais en vain ...
    Veuillez essayer vous meme !!
    Merci
    OOOps je ne peux uploader le zip ...
    Envoyer moi vos email a bsaidus@gmail.com et je vous envoie le zip
    Dhukmucmur Vernedh

  9. #9
    Membre éprouvé
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 45

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Points : 1 294
    Points
    1 294
    Par défaut
    dans le code C tu devrait avoir :

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    int __cdecl WGFGetFileFromHttp6(const PWGFHttpFile * aPHttpFile) {
     
      while (...)
      { /* loop start */
     
        if (*aPHttpFile.Spt != null)
          *aPHttpFile.Spt(*aPHttpFile.Caller, ..., ..., ..., ...);
     
        if (*aPHttpFile.WPrg != null)
          *aPHttpFile.WPrg(*aPHttpFile.Caller, ..., ..., ...);
      } /* loop end */
    }
     
    int __cdecl WGFGetFileFromHttp8(const PWGFHttpFile * aPHttpFile) {
     
      while (...)
      { /* loop start */
     
        if (*aPHttpFile.Spt != null)
          *aPHttpFile.Spt(*aPHttpFile.Caller, ..., ..., ..., ...);
     
        if (*aPHttpFile.WPrg != null)
          *aPHttpFile.WPrg(*aPHttpFile.Caller, ..., ..., ...);
      } /* loop end */
    }
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

Discussions similaires

  1. Réponses: 13
    Dernier message: 09/02/2007, 16h15
  2. delphi et event viewer
    Par Irene dans le forum Delphi
    Réponses: 1
    Dernier message: 18/07/2006, 11h22
  3. Event sur base de donnée Firebird et programmation delphi
    Par seb8810 dans le forum Connexion aux bases de données
    Réponses: 5
    Dernier message: 16/03/2006, 17h06
  4. Traduction C++/Delphi DLL et function Callback
    Par Crafton dans le forum Langage
    Réponses: 12
    Dernier message: 23/02/2006, 09h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo