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

C++Builder Discussion :

TTimer dans une dll utilisée par une application .net


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut TTimer dans une dll utilisée par une application .net
    Bonjour,

    j'ai une dll écrite en C++ builder qui utilise un TTimer.
    Cette dll est utilisée par 2 applications, une en c++ builder et une en .net
    Le TTimer se déclenche correctement dans cette première application en C++ builder mais pas dans celle en .net
    Quelqu'un a t'il une idée du problème ? Peut être vaut il mieux que j'utilise un timer non issu de la VCL ?
    Merci d'avance !

    Pascale38

  2. #2
    Membre confirmé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Points : 523
    Points
    523
    Par défaut
    Bonjour,

    Je pense que c'est difficile de répondre à ce type de question sans plus de précision.
    Il faudrait voir comment est déclaré la fonction qui utilise le timer et comment elle est appelée par les programmes.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    Oui c'est sûr !!

    Dans mon .cpp (car utilisé par des fonctions membres et non membres du fichier .cpp (c'est peut être ça le problème) je déclare mon timer :

    Dans le constructeur de la classe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	TimerCom = new TTimer(NULL);
    	TimerCom->Interval = 5000;
    	TimerCom->OnTimer = TimerComTimer;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void __fastcall TMicroLink::TimerComTimer(TObject * Sender)
    {
    	TimerCom->Enabled = false;
    	...
    }
    Dans le .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    private:
    	void __fastcall TimerComTimer(TObject *Sender);
    Si c'est l'appli en C++ builder qui lance la dll, tout se passe bien, si c'est l'appli en .net, on ne passe jamais dans la fonction TimerComTimer

    Est ce que ça aide ??
    merci :-)
    Pascale38

  4. #4
    Membre confirmé
    Homme Profil pro
    Consultant technique
    Inscrit en
    Juillet 2002
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consultant technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2002
    Messages : 519
    Points : 523
    Points
    523
    Par défaut
    Tout d'abord, il ne faut pas oublier de faire le delete. Surement dans le destructeur. Sinon, il y aura une fuite de mémoire.

    Ensuite, je ne suis pas un expert en dll mais il me semble qu'il y a une syntaxe à utiliser pour indiquer ce qui est utilisable en dehors de la dll avec le mot dllexport.
    De même, il y a un dllimport dans le programme qui l'utilise.

    Donc, ce qu'il faudrait ce serait plutôt voir comme tout celà est exporté et importé par les différents programmes.
    Car si la dll est réalisé en c++Builder, il n'y a pas de problème pour l'utilisation avec C++Builder puisqu'ils utilisent par défaut le même moyen de déclaration de la fonction (avec un __fastcall).
    Il me semble qu'il faut préciser correctement avec l'autre programme comme on accède aux éléments de la dll.

    Il faudrait que quelqu'un qui connaisse mieux .net et les dll te renseigne. Mais je pense que tu peux partir sur cette piste.

  5. #5
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    pour utiliser ta dll avec du .Net ou du Viual C++ du dois exporter la fonction de ta dll de la manière suivante
    les conventions d'appels ne sont pas identique entre Borland et MS

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    extern "C" void __stdcall __declspec(dllexport) Tafonction()
    pour vérifier le bon fonctionnement de l'exportation tu peux utiliser
    Impdef ou Implib

    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    Bonjour,

    bien sûr qu'il y a un delete, je ne l'ai pas mis car pas pertinent pour mon problème.
    Ensuite les fonctions utilisées par lzs applications appelantes sont bien déclarées avec dllexport,
    le problème n'est pas là, le timer lui n'est utilisé que par des fonctions de la dll qui ne sont pas exportées.

    Merci pour ton aide.
    Pascale38

  7. #7
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut
    le problème que tu décrit est il également présent avec une application Non Managée
    de type Visual C++;
    si oui tu a un problème dans l'exportation des fonctions de ta DLL (convention d'appel , Underscore devant le nom de la fonction, nameManbling)

    autre possibilité : Utilise tu le chargement dynamique de la DLL ou une importation statique?

    un simple dll export sans le préfixer "C" va générer du manbling @@@Tafunction()
    naturellement ca fonctionne avec C++ Builder en importation statique
    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    Bonjour,

    merci pour vos réponses mais je crois que je me fais mal comprendre.
    je n'ai pas de souci avec l'exportation de mes fonctions, tout fonctionne très bien à ce niveau là.

    A l'intérieur de ma dll, j'ai un timer qui ne se déclenche pas si l'application utilisatrice est en .net.
    Ce timer n'est pas directement appelé par les applications mais encapsulé dans ma dll.

    Dans mon fichier .cpp le timer est défini en "global" comme ceci :

    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
     
    TTimer *TimerCom
     
     
    TMaClass::TMaClass()
    {
    	TimerCom = new TTimer(NULL);
    	TimerCom->Interval = 5000;
    	TimerCom->OnTimer = TimerComTimer;
    }
     
    void __fastcall TMaClass::TimerComTimer(TObject * Sender)
    {
    	TimerCom->Enabled = false;
    	// C'est dans cette fonction que je ne passe pas si la dll est utilisée par une appli en .net
    }
    C'est une autre fonction exportée qui va ce gérer de créer cette classe.
    Tout le reste de l'application fonctionne parfaitement et il y a une bonne dizaine de fonctions exportées.

    Merci !
    Pascale38

  9. #9
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Ok il reste encore une autre possibilité
    Tu crée ton TTimer dynamiquement or pour fonctionner ce composant doit avoir accès à la boucle de message Windows (WM_TIMER) dans le cas d'une application Delphi ou C++ Builder cela fonctionne, mais pas dans le cas de .Net ou Visual Car la gestion des messages est différente que dans le modèle de Borland
    Tu peux remplacer ton Timer par un composant maison.

    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  10. #10
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    salut
    petit exemple ci dessous en delphi
    Code delphi : 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
     
    GTTimer Thread Based Timer
     
    Title: GTTimer Thread Based Timer
     
    Question: GTTimer is a Timer Component which delivers the same result as a classic TTimer component but it uses a TThread descentant to implement the logic of the Timer Interval.
    This timer is not based on the window messaging system as the classic TTimer component which makes it more reliable and less resource consuming(supposing you have many timers in your application).
     
    Answer:
    {*******************************************************}
    {                                                       }
    {       GT Delphi Components                            }
    {       GT Threaded Timer                               }
    {                                                       }
    {       Copyright (c) GT Delphi Components              }
    {       http://www.gtdelphicomponents.gr                }
    {                                                       }
    {                                                       }
    {*******************************************************}
    unit o_GTTimer;
     
    interface
     
    uses
      Classes
      ;
     
    type
    {------------------------------------------------------------------------------}
      TgtTimer = class;
    {------------------------------------------------------------------------------}
    TgtTimerThread = class(TThread)
    private
       { Private declarations }
       FTimer : TgtTimer;
    protected
       { Protected declarations }
       procedure DoTimer;
    public
       { Public declarations }
       constructor Create(ATimer : TgtTimer);
       destructor  Destroy;override;
       procedure Execute;override;
    published
       { Published declarations}
    end;
    {------------------------------------------------------------------------------}
      TgtTimer = class(TComponent)
      private
        FEnabled: Boolean;
        FInterval: Cardinal;
        FOnTimer: TNotifyEvent;
        procedure SetEnabled(const Value: Boolean);
        procedure SetInterval(const Value: Cardinal);
        { Private declarations }
      protected
        { Protected declarations }
        FTimerThread : TgtTimerThread;
        procedure UpdateTimer;
      public
        { Public declarations }
        constructor Create(AOwner:TComponent);override;
        destructor  Destroy;override;
      published
        { Published declarations}
        property Enabled : Boolean  read FEnabled  write SetEnabled;
        property Interval: Cardinal read FInterval write SetInterval;
      published
        property OnTimer : TNotifyEvent read FOnTimer write FOnTimer;
      end;
    {------------------------------------------------------------------------------}
     
    implementation
    uses
       Windows
      ,SysUtils
      ;
     
    { TgtTimerThread }
    {------------------------------------------------------------------------------}
    constructor TgtTimerThread.Create(ATimer: TgtTimer);
    begin
      inherited Create(True);
      FreeOnTerminate := True;
      FTimer          := ATimer;
    end;
    {------------------------------------------------------------------------------}
    destructor TgtTimerThread.Destroy;
    begin
      inherited;
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimerThread.DoTimer;
    begin
      if Assigned(FTimer.OnTimer) then
        FTimer.OnTimer(FTimer);
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimerThread.Execute;
    begin
      while (not Self.Terminated) and (FTimer.Enabled) do
      begin
        WaitForSingleObject(Self.Handle,FTimer.Interval);
        Synchronize(DoTimer);
      end;
    end;
    {------------------------------------------------------------------------------}
     
    { TgtTimer }
    {------------------------------------------------------------------------------}
    constructor TgtTimer.Create(AOwner: TComponent);
    begin
      inherited Create(AOwner);
      FEnabled  := True;
      FInterval := 1000;
    end;
    {------------------------------------------------------------------------------}
    destructor TgtTimer.Destroy;
    begin
      inherited;
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimer.UpdateTimer;
    begin
      if Assigned(FTimerThread) then
      begin
        FTimerThread.Terminate;
        FTimerThread := nil;
      end;
      if Enabled then
      begin
        FTimerThread := TgtTimerThread.Create(Self);
        FTimerThread.Resume;
      end;
    end;
    {------------------------------------------------------------------------------}
     
    //Getters - Setters\\
    {------------------------------------------------------------------------------}
    procedure TgtTimer.SetEnabled(const Value: Boolean);
    begin
      FEnabled := Value;
      UpdateTimer;
    end;
    {------------------------------------------------------------------------------}
    procedure TgtTimer.SetInterval(const Value: Cardinal);
    begin
      if Value  FInterval then
      begin
        FInterval := Value;
        UpdateTimer;
      end;
    end;
    {------------------------------------------------------------------------------}
     
    end.
    http://delphi.cjcsoft.net//viewthread.php?tid=47384

    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    merci DjmSoftware,
    tu confirmes mon idée première qu'il ne faut pas que j'utilise un composant de la VCL...

    Je vais remplacer ce timer et si ça fonctionne je mettrai la discussion a résolue.
    ça va prendre un petit peu de temps car pas dans les priorités immédiates du projet pour l'instant ;-)

    Merci encore à tous!
    Pascale38

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    229
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 229
    Points : 79
    Points
    79
    Par défaut
    oh super !!
    Merci pour l'exemple !!!

  13. #13
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    ou alors en c++ un excellent article en anglais
    http://bcbjournal.org/forums/viewtopic.php?f=10&t=572#
    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  14. #14
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Je me demande si tu n'aurais pas pu créer un timer en passant par les API WINDOWS directement au lieu de passer par TTimer.
    Au quel cas il suffisait de passer une fonction pour le time out du timer en lieu et place d'avoir à gérer le WM_TIMER.
    Au fond, à ce stade on serait plus près du hardware que du software !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    UINT SetTimer(
     
        HWND hWnd,	// handle of window for timer messages
        UINT nIDEvent,	// timer identifier
        UINT uElapse,	// time-out value
        TIMERPROC lpTimerFunc 	// address of timer procedure
       );
    La timerproc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    VOID CALLBACK TimerProc(
     
        HWND hwnd,	// handle of window for timer messages 
        UINT uMsg,	// WM_TIMER message
        UINT idEvent,	// timer identifier
        DWORD dwTime 	// current system time
       );
    Mais je ne sais pas si c'est faisable dans ton cas !

    A plus !

  15. #15
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Problème identique
    la boucle de message
    le Callback utilise un HWND qui n'est pas directement présent dans ce cas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    VOID CALLBACK TimerProc(
     
        HWND hwnd,	// handle of window for timer messages 
        UINT uMsg,	// WM_TIMER message
        UINT idEvent,	// timer identifier
        DWORD dwTime 	// current system time
       );
    --> solution des event

    cdlt
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  16. #16
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    HWND peut être NULL dès le SetTimer !
    Celà signifie que le message WM_TIMER ne passera pas par une quelconque procédure de fenêtre (puisque aucun HWND ne lui est associé).
    WM_TIMER est alors transmis via la TimerProc pour y être éventuellement traité. C'est à ça que sert le paramètre UINT uMsg de la callback.

    A plus !

  17. #17
    Membre chevronné

    Profil pro
    Inscrit en
    Juin 2002
    Messages
    1 374
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 374
    Points : 1 759
    Points
    1 759
    Par défaut
    Salut !

    Je viens de vérifier dans l'un de mes anciens projets (non pas avec BCB mais avec DEVCPP).
    Je passais bien un HWND valide dans la settimer mais le hwnd de la timerproc n'était pas utilisé !
    Donc depuis cette timerproc je faisais appel à une fonction pour effectuer le traitement suite au timeout du timer.

    BCB implémente en arrière plan un timer qui transmet des messages WM_TIMER dans la procédure de la fenêtre.
    Si on veut faire autrement il fait passer par la strate des API WINDOWS.

    A plus !

Discussions similaires

  1. Réponses: 8
    Dernier message: 18/02/2016, 04h56
  2. DLL utilisées par une application Qt
    Par black_hole dans le forum Débuter
    Réponses: 2
    Dernier message: 15/01/2013, 10h43
  3. Réponses: 4
    Dernier message: 02/12/2011, 14h52
  4. Utilisation d'une dll native par une toolbar managée
    Par didierll dans le forum C++/CLI
    Réponses: 1
    Dernier message: 10/07/2007, 07h56
  5. Réponses: 1
    Dernier message: 01/11/2005, 02h29

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