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

Langage Delphi Discussion :

Stdcall, Langage C et fonction dans type


Sujet :

Langage Delphi

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Avril 2011
    Messages : 7
    Points : 4
    Points
    4
    Par défaut Stdcall, Langage C et fonction dans type
    Bonjour,

    voici un cas d'appel à une DLL suite à une traduction dans C :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    uses  Windows;
     
    type
    DATADETECTEDPROC=function(const pData:pbyte; ulSize:DWORD ; pContext:pointer):integer; stdcall;
    FN_CONTEXT   =   record
    ulFlags:dword;
    pfnDataDetected:DATADETECTEDPROC   ;
    pContext:pointer;
    end;
    PFN_CONTEXT=^FN_CONTEXT;
    type PCFN_CONTEXT=   ^FN_CONTEXT   ;
     
    function  InitCommContext(pContext:PCFN_CONTEXT   ):integer;stdcall; external 'madll.dll';
    function  ExitCommContext():integer;stdcall; external 'madll.dll';
    J'ai un soucis sur l'utilisation du DATADETECTEDPROC qui dans le langage C, n'est pas un appel en extérieur mais une fonction implémentée dans le code au dessus du create :

    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
     
    long __stdcall onDataDetected(const unsigned char *pData, unsigned long ulSize, void *pContext)
    {
    	CDllIDRD_U_DemoDlg *p = (CDllIDRD_U_DemoDlg *)pContext;
    	unsigned char *pBuffer = new unsigned char[ulSize+1];
    	memcpy(pBuffer, pData, ulSize);
    	pBuffer[ulSize] = 0;
    	CString str;
    	p->GetDlgItemText(IDC_EDIT1, str);
    	str += pBuffer;
    	p->SetDlgItemText(IDC_EDIT1, str);
    	delete [] pBuffer;
    	return 0;
    }
     
    int CDllIDRD_U_DemoDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
    	if (CDialog::OnCreate(lpCreateStruct) == -1)
    		return -1;
     
    	// TODO: Add your specialized creation code here
    	FN_CONTEXT clsFnContext =
    	{
    		1, // 0±íʾ±ê×¼×Ö·û¸ñʽ¡¢1±íʾʮÁù½øÖƸñʽ
    		onDataDetected,
    		this
    	};
    	if(InitCommContext(&clsFnContext) != 0)
    	{
    		AfxMessageBox("Différent");
    		return -1;
    	}
    	AfxMessageBox("Egal");
    	return 0;
    }

    Et actuellement j'ai :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    procedure TForm1.FormCreate(Sender: TObject);
    var
    OnDataDetected : DATADETECTEDPROC;
    begin
     New (clsFnContext);
    clsFnContext.ulFlags := 1;
    clsFnContext.pfnDataDetected := OnDataDetected;
    clsFnContext.pContext := self;
    if InitCommContext(clsFnContext) = 0  Then Memo1.Lines.Add('Connecté') else Memo1.Lines.Add('Pas Connecté');
    end;
    Il me dit "connecté" mais quand je passe ma carte sur la machine, j'ai une erreur de violation d'accès (on dirait qu'il ne fait pas le lien avec une fonction OnDataDetected que j'ai crée)

    Donc j'arrive facilement à gérer les appels à l'initCommContext et à l'Exit, mais je ne sais pas comment gérer cette fonction OndataDetected sous Delphi (6), auriez vous une idée svp ?

    Merci beaucoup !

  2. #2
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 170
    Points
    4 170
    Par défaut
    Je pense que tu as une erreur dans la traduction du prototype de DATADETECTEDPROC sur le paramètre pData.

    En C, le mot clé const n'a pas le même effet qu'en Delphi. Il indique seulement au compilateur que le paramètre ne doit pas être modifié.
    Alors qu'en delphi, il induit en plus un passage par référence.

    Autrement dit, la traduction Delphi conduit à un pointeur sur un PByte, qui est déjà un pointeur sur un byte. Alors qu'en C, il n'y avait qu'un seul niveau de pointeur.

    Essaie en enlevant le mot clé const dans la définition Delphi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    type
      DATADETECTEDPROC=function(const pData:pbyte; ulSize:DWORD; pContext:pointer):integer; stdcall;

  3. #3
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 859
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 859
    Points : 11 303
    Points
    11 303
    Billets dans le blog
    6
    Par défaut
    On doit aussi pouvoir le traduire en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      DATADETECTEDPROC = function(var Data: TByteArray; Size: Cardinal; Context: Pointer): integer; stdcall;
    Intérêt sous Lazarus plus que sous Delphi car le premier ne déréférence pas automatiquement les pointeurs...
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  4. #4
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Avril 2011
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Merci pour vos réponses.

    Je me suis rendu compte que je ne vous avais pas mis la code C original !

    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
     
    #ifdef __cplusplus
    extern "C"
    {
    #endif
     
    typedef long (__stdcall *DATADETECTEDPROC)(const unsigned char *pData, unsigned long ulSize, void *pContext);
    typedef struct _FN_CONTEXT
    {
    	unsigned long ulFlags;
    	DATADETECTEDPROC pfnDataDetected;
    	void *pContext;
    } FN_CONTEXT, *PFN_CONTEXT;
    typedef const FN_CONTEXT *PCFN_CONTEXT;
     
    long __stdcall InitCommContext(PCFN_CONTEXT pContext);
    long __stdcall ExitCommContext();
     
    #ifdef __cplusplus
    }
    #endif
    J'ai tenté en enlevant le Const ou en mettant la déclaration fournie par tourloulou, c'est le même résultat, à savoir quand quand je passe ma carte devant la machine, le programme plante par une violation d'accès en s'arrêtant sur "Thread := nil;" dans "procedure TThreadLocalCounter.Close(var Thread: PThreadInfo);" de Sysutils.

    Mais ce qui m'embête surtout, c'est comment créer cette fonction sous Delphi sachant que dans C, elle sert dans une déclaration de type dans le .h et qu'elle est créée dans le .cpp mais qu'en même temps elle sert à la création de la fonction InitCommContext de la DLL. Je n'arrive pas à faire le lien ;(

    Merci encore

Discussions similaires

  1. Utiliser les fonctions dans le langage c
    Par dev0712 dans le forum Débuter
    Réponses: 3
    Dernier message: 14/12/2008, 20h41
  2. Réponses: 11
    Dernier message: 18/02/2007, 15h37
  3. [langage] Appel de fonction dans un lien
    Par drakan dans le forum Langage
    Réponses: 1
    Dernier message: 17/05/2005, 18h30
  4. Réponses: 4
    Dernier message: 26/01/2005, 13h08
  5. [langage] Passage de paramètres dans une fonction
    Par And_the_problem_is dans le forum Langage
    Réponses: 11
    Dernier message: 28/06/2004, 08h20

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