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++ Discussion :

passage de paramètre dans l'appel d'une fonction venant d'une dll (C++ & Delphi)


Sujet :

C++

  1. #21
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 74
    Par défaut
    J'ai l'impression wue le de C++ n'est pas "codé" de la même façon que le de delphi

    D'après l'aide de delphi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Définit une chaîne terminée par null. 
     
     
     
     
    PChar définit un pointeur sur un emplacement mémoire qui contient des valeurs WideChar (y compris le caractère #0).
    est-ce bien celà que je crée en utilisant wchar_t* en C++?

  2. #22
    screetch
    Invité(e)
    Par défaut
    oui, si les deux sont bien codes sur 2 octets (c'est normalement le cas)

  3. #23
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Par défaut
    Je comprends pas ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System::Convert::ToString(gcnew String(res))
    Tu convertis une String en String.

    Et ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myString := pChar(txt);
    Tu convertis un PChar en PChar.

    Pense à déclarer explicitement le __sdtcall en C++, sais-tu au moins quelle est la convention par défaut dans ton compilo ?

    Maintenant, je ne comprends pas comment en renvoyant txt tel quel tu peux avoir un résultat différent... Affiche-le avant et après l'appel à la fonction.

  4. #24
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 74
    Par défaut
    Citation Envoyé par Hibernatus34 Voir le message
    Je comprends pas ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System::Convert::ToString(gcnew String(res))
    Tu convertis une String en String.
    effectivement, gcnew String(res) semble suffisant
    j'avais trouvé ce code pour convertir std::wdstring en System::String, comme ça marchait j'ai pas cherché plus loin

    Citation Envoyé par Hibernatus34 Voir le message
    Et ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    myString := pChar(txt);
    Tu convertis un PChar en PChar.
    Tu as raison, ... je ne sais pas trop comment on convertit, d'après les infos que j'ai trouvé, une simple assignation du PChar dans un string fait la convertion (ou bien via StrPas())

    Citation Envoyé par Hibernatus34 Voir le message
    Pense à déclarer explicitement le __sdtcall en C++, sais-tu au moins quelle est la convention par défaut dans ton compilo ?

    Maintenant, je ne comprends pas comment en renvoyant txt tel quel tu peux avoir un résultat différent... Affiche-le avant et après l'appel à la fonction.
    BINGOOOOOOOOOOOOO

    J'avais lu sur le net que le __stdcall était "par défaut" donc je ne l'ai pas ajouté.
    J'avais tout de même fait une tentative avec, qui avait échouée car j'avais probablement une autre erreur.

    Voilà, donc en définitive, ça marche.
    Un grand merci pour ton aide, (pareil pour les autres intervenants.)
    Je ne suis pas encore au bout de mes peine vu que c'était une fonction "test", mais si la base marche, le reste suivra.

    Je colle ci-dessous le code fonctionnel, pour que les choses soient claires.

    Delphi
    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
    function _sbHelloParam(txt:Pchar):Pchar; stdcall;
      var
        res : Pchar;
        myString2 : string;
        IniFile : TIniFile;
     begin
     
      myString2 := StrPas(txt);
     
      IniFile := TIniFile.Create('C:\Windows\zzz_ctest.ini');
      IniFile.WriteString('delphiresult', 'myString2', myString2);
      IniFile.WriteString('delphiresult', 'txt', txt);
      IniFile.Free;
     
      Result := txt;
     end ;
    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
    15
    16
    	private: System::Void bt_sbHelloParam_Click(System::Object^  sender, System::EventArgs^  e) {
     
    				typedef  wchar_t* (__stdcall *fct_sbHelloParam)(wchar_t* wtxt);
    				fct_sbHelloParam fsbHelloParam;
     
    				fsbHelloParam = (fct_sbHelloParam)GetProcAddress(hInstLibrary, "_sbHelloParam");
    				if (fsbHelloParam){
     
    					wchar_t* wtxt = L"test";
    					wchar_t* res = fsbHelloParam(wtxt);
    					this->tbLog->Text += "res="+gcnew String(res)+ "\r\n";
    				}else{
    					this->tbLog->Text += "GetProcAddress for _sbHelloParam failed !" + "\r\n";
    				}
     
    		 }

  5. #25
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Mais qui et quand est libérée la chaîne résultat ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  6. #26
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 74
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Mais qui et quand est libérée la chaîne résultat ?
    Je ne sais pas trop ce qu'il faut libérer ni quand ...

    qui ? .. ma fonction C++ après l'appel à la fonction Delphi.

  7. #27
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Mais qui et quand est libérée la chaîne résultat ?
    Pour l'instant il se contente de renvoyer le pointeur qui appartient à l'appelant.
    Il va comprendre le problème quand il voudra renvoyer un vrai résultat.

  8. #28
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 74
    Par défaut
    Citation Envoyé par Hibernatus34 Voir le message
    Pour l'instant il se contente de renvoyer le pointeur qui appartient à l'appelant.
    Il va comprendre le problème quand il voudra renvoyer un vrai résultat.
    Tout juste ...

    Voici un exemple type des autres fonctions que je vais devoir utiliser ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function _sbHelloParam(txt:Pchar):Pchar; stdcall;
      var
        Res : Pchar;
        TmpTxt : string;
     begin
      TmpTxt := StrPas(txt);
      GetMem(res, length(TmpTxt));
      StrPCopy(res,sbHelloParam(TmpTxt)) ;
      Result := res;
     end ;
    et effectivement ... quand faire mon freemem ???

  9. #29
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Par défaut
    J'espère que Length() renvoie un nombre d'octets, (longueur + 1) * 2, et non un nombre de caractères, sinon ta fonction est buggée.

    Comment faire ?
    Il faut simplement avoir une String qui est garantie d'exister avant et après l'appel à la fonction.
    Ca peut être un membre d'un objet auquel on accède avec cette fonction.
    Ca peut aussi être une simple globale.

    Et donc tu fais pas d'allocation à chaque appel de la fonction. Pas explicitement du moins.

  10. #30
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 74
    Par défaut
    Citation Envoyé par Hibernatus34 Voir le message
    J'espère que Length() renvoie un nombre d'octets, (longueur + 1) * 2, et non un nombre de caractères, sinon ta fonction est buggée.

    Comment faire ?
    Il faut simplement avoir une String qui est garantie d'exister avant et après l'appel à la fonction.
    Ca peut être un membre d'un objet auquel on accède avec cette fonction.
    Ca peut aussi être une simple globale.

    Et donc tu fais pas d'allocation à chaque appel de la fonction. Pas explicitement du moins.
    Je pense que le length n'est pas bon, ... je vais devoir le changer.


    Question:

    En supposant que je crée une (des) variable(s) globale(s) pour mes pointeurs dans Delphi. (donc dans ma DLL)

    Faut-il faire des "FreeMem" à un moment ou l'autre, ou, l'espace mémoire aloué est-il libéré lorsqu'on fait un unload de la dll (depuis C++)

  11. #31
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 74
    Par défaut
    Citation Envoyé par Hibernatus34 Voir le message
    J'espère que Length() renvoie un nombre d'octets, (longueur + 1) * 2, et non un nombre de caractères, sinon ta fonction est buggée.
    Je ne trouve pas l'info indiquée dans l'aide extremement clair.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [edit] Description
     
    Renvoie le nombre de caractères d'une chaîne ou d'éléments d'un tableau. 
     
     
     
     
    Dans le code Delphi, Length renvoie le nombre de caractères effectivement utilisés dans la chaîne ou le nombre d'éléments dans le tableau. Dans le code C++, utilisez la méthode portant le même nom sur la classe AnsiString ou DynamicArray. 
     
    Pour des chaînes à un seul octet et multi-octets, Length renvoie le nombre d'octets utilisés par la chaîne. Pour des chaînes Unicode (WideString), Length renvoie le nombre d'octets divisé par deux.
    je devrais faire * 2 .

    pour des chaine unicode ca renvoie le nombre d'octet divisé par 2 ?
    faut-il traduire ça par ... ca renvoie le nombre de caractère, mais comme les caractère sont sur 2 octet, c le nombre d'octet /2 ???

  12. #32
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Par défaut
    C'est pas simple :
    Une globale fait partie du module. Quand un module est déchargé, la globale aussi...
    .. mais le type String contient un pointeur sur les caractères qui le compose. Ce pointeur pointe sur le tas.
    Normalement, je dirais que les compilo Delphi et C++, qui peuvent avoir des globales avec destructeurs, ont la responsabilité d'appeler ces destructeurs au déchargement d'une DLL, et donc j'ose espérer que ça marche correctement.
    Mais franchement, une DLL c'est pas fait pour être chargé/déchargé souvent. On voudra souvent qu'une DLL reste chargée en permanence à partir du premier usage.

  13. #33
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Par défaut
    Citation Envoyé par vin100H Voir le message
    je devrais faire * 2 .

    pour des chaine unicode ca renvoie le nombre d'octet divisé par 2 ?
    faut-il traduire ça par ... ca renvoie le nombre de caractère, mais comme les caractère sont sur 2 octet, c le nombre d'octet /2 ???
    Il n'existe pas une fonction qui renvoie toujours le nombre d'octets ?

  14. #34
    Membre confirmé
    Profil pro
    Inscrit en
    Août 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2007
    Messages : 74
    Par défaut
    Citation Envoyé par Hibernatus34 Voir le message
    Il n'existe pas une fonction qui renvoie toujours le nombre d'octets ?
    Si SizeOf existe bien.

    Merci.

  15. #35
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    732
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 732
    Par défaut
    Si c'est le même sizeof qu'en C++, alors c'est pas ce que tu veux.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. [JavaScript] [FAQ] Appeler dynamiquement une fonction et passer une fonction en argument
    Par SpaceFrog dans le forum Contribuez
    Réponses: 0
    Dernier message: 28/05/2008, 14h48
  2. Réponses: 2
    Dernier message: 26/04/2008, 17h31
  3. Réponses: 4
    Dernier message: 30/11/2007, 14h46
  4. Appel d'une fonction A depuis une fonction B.
    Par LeFlou dans le forum C++
    Réponses: 9
    Dernier message: 22/05/2007, 17h36
  5. Passer une fonction comme argument à une fonction
    Par Cocotier974 dans le forum Général Python
    Réponses: 4
    Dernier message: 29/06/2004, 13h41

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