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 :

D2010 - Types à utiliser pour passer des chaines avec une dll


Sujet :

Langage Delphi

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 20
    Points
    20
    Par défaut D2010 - Types à utiliser pour passer des chaines avec une dll
    Bonjour à tous!
    Je viens de passer de delphi 2005 à delphi 2010, et même si je savais que le changement de gestion des chaines pour

    supporter l'unicode pourrait poser problème, je ne pensais pas en avoir autant.

    Le contexte: J'utilise dans Access (donc en VBA) la fonction ci dessous, exportée depuis une dll.

    Voici le code que j'utilise dans ma DLL (donc fonctionnel avec delphi 2005)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    procedure SetDataBasePath(DatabasePath: PString; SysDatabasePath: PString); stdcall; export;
    var
      DBP: String;
      SDP: String;
    begin
        DBP := String(databasePath);
        SDP := string(SysDatabasePath);
        //...
    end;
    Voici comment elle est déclarée et utilisée dans Access:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Declare Sub SetDataBasePathA Lib "madll.ocx" Alias "SetDataBasePath" (ByVal DatabasePath As String, ByVal SysDatabasePath As String)
     
    ...
     
    SetDataBasePathA "chemindemabaseaccess", "chemindemonfichierdesécu"
    Evidemment, avec delphi 2010 cela me fait de chaines DBP et SDP vides.

    Ma question est donc celle-ci: Quel type dois-je choisir pour ma fonction, et comment traiter les valeurs récupérées pour que cela fonctionne avec delphi 2010 ?

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 563
    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 563
    Points : 25 165
    Points
    25 165
    Par défaut
    PString ? ça fonctionne ça ?
    ça donne quand même pointeur de pointeur de tableau de char

    Remplace par PAnsiString (PAnsiString = ^AnsiString), si tu veux conserver la même méthode

    en théorie var ou const, on le même effet, passage par référence et non par valeur, bon pour les chaines en delphi c'est plus subtile, je sais que cela fonctionne très bien pour les Record et les types comme Integer, ... mais pour string, je n'utilise jamais ce type pour les DLL à cause de la même mémoire partagée (Bordelmm.dll)

    D2005
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure SetDataBasePath(const DatabasePath: String; const SysDatabasePath: PString); stdcall; export;
    D2010
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure SetDataBasePath(const DatabasePath: AnsiString; const SysDatabasePath: AnsiString); stdcall; export;
    Enfin, voir si ceci fonctionne en D2005 et D2010

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    procedure SetDataBasePath(DatabasePath: PAnsiChar; SysDatabasePath: PAnsiChar); stdcall; export;

  3. #3
    Membre éprouvé Avatar de BuzzLeclaire
    Homme Profil pro
    Dev/For/Vte/Ass
    Inscrit en
    Août 2008
    Messages
    1 606
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Dev/For/Vte/Ass

    Informations forums :
    Inscription : Août 2008
    Messages : 1 606
    Points : 1 113
    Points
    1 113
    Par défaut
    @Salut,

    J'ai eu la même problèmatique récement, voilà ce que je fais actuellement.

    Dans ma Dll je déclare comme 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
    procedure Test(Base: PChar); StdCall;
    Var
    // ...
    Begin
      Cnx := TADOConnection.Create(nil);
      try
        with Cnx do
        begin
          Provider := 'Microsoft.Jet.OLEDB.4.0';
          ConnectionString :='Data Source=' +
                              Base +
                              ';Persist Security Info=False';
    // ...
    end;
    Et dans le soft je l'appel comme ceci (moi je suis en DLL dynamique).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    //....
                      @Test := getprocaddress(DllInstance,'Test');
                      if Assigned(Test) then
                      begin
                        Test(PChar(Chemin_et_Base));
    //...
    @+

  4. #4
    Membre à l'essai
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 20
    Points
    20
    Par défaut
    @BuzzLeclaire :
    Merci pour ta contribution mais cela ne s'applique pas du tout à mon cas (j'utilise ma dll dans VBA qui ne supporte pas unicode).

    @ShaiLeTroll
    Merci pour ta proposition d'utiliser directement le type Ansistring.

    Maintenant j'utilise ceci dans ma déclaration, ce qui me permet de récupérer dans ma fonction des valeurs correctes sous la forme d'ansistring:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    procedure SetDataBasePath(DatabasePath: AnsiString; SysDatabasePath: AnsiString); stdcall; export;
    begin
     //...
    end;
    Le problème est que mes variables DatabasePath et SysDatabasePath sont maintenant des ansistring, et que je dois en faire des unicodestring pour pouvoir les utiliser avec delphi dans l'optique de support de l'unicode (et éviter de réécrire tout mon code pour lui dire de ne pas le supporter, ce qui serait idiot tout de même)...

  5. #5
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 563
    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 563
    Points : 25 165
    Points
    25 165
    Par défaut
    Soit tu utilise le type string directement, mais tout vient de l'appel de le VBA, il faut que ses string à lui soit aussi en unicode !
    Regarde aussi WideString qui est le type BSTR Automation, il est géré différement !

    enfin, tu devrais utiliser plutôt un ActiveX (fonction en safecall), c'est plus normé qu'une DLL !
    en VBS (le VBA doit être équivalent), avec CreateOleObject tu peux instancier ton objet, ensuite tu l'utilise en LateBinding ...

  6. #6
    Membre à l'essai
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 20
    Points
    20
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Soit tu utilise le type string directement, mais tout vient de l'appel de le VBA, il faut que ses string à lui soit aussi en unicode !
    Regarde aussi WideString qui est le type BSTR Automation, il est géré différement !
    J'ai déjà tenté WideString, mais il est maintenant basé sur unicode dans delphi.
    Pour ce qui est de gérer l'appel de la fonction en unicode dans VBA j'adorerais, mais je vois pas du tout comment il faudrait que je m'y prenne, vla la diversité des types dans Access (2000 en plus) ...

  7. #7
    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
    regarde TEncoding dans SysUtils

    mais logiquement tu n'as besoin que de deux types pour travailler en Ansi :
    AnsiString, AnsiChar et PAnsiChar.

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/03/2012, 15h01
  2. [XL-2003] Pb pour comparer des chaines dans une fonction
    Par comme de bien entendu dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 22/09/2011, 19h53
  3. Problèmes pour tracer des graphiques avec une macro
    Par Margoooot dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 21/08/2011, 17h19
  4. [Smarty] Un probleme pour passer des variables avec Smarty
    Par aztec dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 31/03/2008, 15h01
  5. Réponses: 2
    Dernier message: 04/10/2005, 20h54

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