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

Bibliothèques Discussion :

Problème complexe de dll utilisé avec Access


Sujet :

Bibliothèques

  1. #1
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut Problème complexe de dll utilisé avec Access
    Bonjour à tous
    J'ai une colle et je voudrais savoir si quelqu'un pourrait m'éclairer.
    Je suis en train de développer des dlls pour ne plus utiliser les modules sous Access. Jusque là tout va bien.
    J'ai un fichier .h :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    extern "C" export int __stdcall Addition(int, int ); 
    extern "C" export BSTR __stdcall TravailSurChaine(char* );
    et un fichier .cpp :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    extern "C" int __stdcall Addition(int a, int b )
    {
        return a + b;
    }
     
    extern "C" BSTR  __stdcall TravailSurChaine(char* Nom)
    {
        return (SysAllocStringByteLen(strrev(Nom), strlen(Nom)));
    }
    Pour avoir deux exemples, un sur des chiffres et l'autre sur des chaines de caractères. J'ai bien lu les trucs sur BSTR et tout ca.
    Quand j'appelles ces fonctions dans le code pas de soucis tout fonctionne bien. Par contre un truc pratique c'est que les fonctions peuvent utiliser dans le requêtes.
    Ainsi si je fais dans une requete "SELECT Addition([Champ1],[Champ2]) FROM MaTable", ca marche aussi.
    Mais si je fais "SELECT TravailSurChaine([Champ1]) FROM MaTable", j'obtiens bien mon nombre d'enregistrement mais pour chaque enregistrement mon champ est vide ? Du coup je comprend pas dans le code ca marche, dans les requêtes pour les champs numériques ca marche mais avec des chaines de caractères ca retourne une valeur nulle. C'est peut-être un problème de perte d'adressage dû à SysAllocStringByteLen mais je vois pas.
    Si vous avez une idée merci beaucoup

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    La BSTR obtenue par SysAllocStringByteLen() n'est pas une BSTR "texte" valide, elle est considérée comme étant des données binaires.

    Pour que la BSTR soit une chaîne valide, tu dois utiliser une chaîne de wchar_t et non une chaîne de char.

    PS: À quoi sert strrev() ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut
    Merci pour ta réponse
    J'ai lu partout que la correspondance String en Vb était BSTR en C++, c'est pour ca que j'ai utilisé ca.
    Je viens de modifier ma fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    extern "C" wchar_t*  __stdcall TravailSurChaine(char* Nom)
    Mais le résultat est le même quand je fais un bout de code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Dim Temp as String
    Temp = TravailSurChaine("Toto")
    MsgBox Temp
    Ca marche nickel il m'affiche "otot" mais quand je fais ca dans une requete il me retourne encore des champs vides ...

    PS : le strrev c'est juste histoire de faire qqc sur ma chaine (ca retourne la chaine inversée)

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    VB peut être plus tolérant que d'autres choses...
    Essaie en convertissant la chaîne en unicode avant de faire un SysAllocString() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    extern "C" BSTR  __stdcall TravailSurChaine(char* Nom)
    {
        strrev(Nom);
     
        std:wostringstream ossW;
        ossW << Nom;
        std::wstring NomW = ossW.str();
        return SysAllocString(NomW.c_str());
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Tu peux aussi essayer ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    extern "C" BSTR  __stdcall TravailSurChaine(char const * Nom)
    {
        std:wostringstream ossW;
        ossW << Nom;
        std::wstring NomW = ossW.str();
        BSTR bsNom = SysAllocString(NomW.c_str());
     
        wcsrev(bsNom);
        return bsNom;
    }
    Ce qui a l'avantage de ne pas modifier la chaîne passée en paramètre.
    Mais je ne garantis pas que ça marchera, je ne sais plus si SysAllocString() place ou non un caractère nul à la fin de la chaîne.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  6. #6
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut
    Je suis désolé je suis pas encore très au point sous c++, j'ai ajouté ton code mais il ne compile pas il ne reconnait pas wostringstream. Je dois inclure quoi ? (Pour info je suis sous VS 6)
    Merci encore de ton aide

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Normalement, le fichier d'en-tête est <sstream>.
    Si Visual ne reconnait pas, essaie avec std::basic_ostringstream< wchar_t > (wostringstream est juste un typedef sur le template)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut
    Salut Médinoc
    Merci pour tes répondes mais malheureusement ca ne marche toujours pas dans les requetes et en plus dans le code ca me place un caractère \0 après chaque caractère.
    Si tu as une autre idée je suis preneur

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Sonic
    ca me place un caractère \0 après chaque caractère.
    Ça, c'est typiquement ce qui arrive quand on prend une chaîne unicode UTF-16 ou UCS-2 (ou une BSTR) pour une chaîne en ASCII étendu.

    Il y a donc quelque part un ou plusieurs bouts de code qui prennent des BSTR pour ce qu'elles ne sont pas: Des chaînes en ASCII étendu...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  10. #10
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut
    Salut Médinoc
    J'ai essayé de faire un simple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    BSTR bsNom = SysAllocString(L"toto");
    return bsNom;
    Alors dans la requete ca marche j'obtiens bien dans chaque ligne "toto" mais maintenant dans le code ma variable contient chaque caractère séparé d'un \0 ???
    Ca marche dans un sens et pas dans l'autre à chaque fois.

    PS : je viens d'essayer ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return (SysAllocStringByteLen(strrev(Nom) + '\0', strlen(Nom)+1))
    Dans le code j'obtiens ma chaine + le caractère \0 (représenté par un carré) et dans ma requete j'obtiens que le 1° caractère ? C'est étrange comme comportement

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Qu'appelles-tu "dans le code" ?

    Un caractère unicode UTF-16 ou UCS-2 fait deux octets, dont l'octet haut est nul pour tous les caractères Latin-1.
    Si tu ajoutes un caracter non Latin-1 comme le symbole Euro, tu verras que l'octet haut n'est pas nul pour le carcatère en question.

    Sachant qu'une BSTR est en UCS-2 sous WinNT4 et en UTF-16 sous Win2000 ou supérieur, c'est parfaitement normal.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut
    En fait je souhaite utiliser ma fonction dans 2 cas distincts :
    1) Dans mon code vb tout betement où je fais un truc tout simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Dim Temp as string
    Temp=TravailSurChaine("MaChaine")
    2) Sous Access, le truc pratique c'est qu'on peut utiliser une fonction du code vb pour calculer des trucs, à la manière des procédures stockées. C'est à dire que si j'ai une fonction dans mon module vb :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public function TravailSurChaine(ByVal MaChaine as string) as String
       TravailSurChaine=MaChaine
    end function
    Je peux faire une requete "SELECT TravailSurChaine([Champ1]) FROM MaTable". Ainsi c'est la même fonction dans le code et dans ma requete, ce qui est très pratique. Le problème c'est qu'apparemment le format string n'a pas l'air d'être le même que ce soit un retour de la fonction "dans le code" que "dans la requete" car dans un cas ca marche et pas dans l'autre et vice-versa.
    J'espère que c'est plus clair. En tout cas je te remercie de ton aide

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Je ne connais pas Access, mais les chaînes VB sont supposées être des BSTR en unicode.
    Regarde s'il n'y a pas deux types de string différents dans Access : C'est courant, dans les SGBD...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  14. #14
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut
    Je viens d'essayer de trouver sur le format enregistré : Un champ CHAR est toujours enregistré dans le format de représentation Unicode (cf)
    Comme le BSTR est en unicode aussi il ne devrait pas y avoir de problème, je vois pas ...

  15. #15
    Membre régulier Avatar de Sonic
    Inscrit en
    Mars 2002
    Messages
    105
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 105
    Points : 96
    Points
    96
    Par défaut
    Je viens de tout tracer au pas à pas en hexa pour voir les différences et voilà ce que j'obtiens (pour une chaine "toto"):
    Par le code, VB attends une chaine unicode de type BSTR codé sur 1 octet
    soit 84 79 84 79 00 00 00 ...
    Et dans une requete le retour est une chaine codée sur 2 octets soit :
    84 00 79 00 84 00 79 00 00 00 ...
    A moins qu'il existe un type qui fasse les 2 en memes temps, je crois que c'est impossible à résoudre (sans faire 2 fonctions, une pour chaque cas) ...
    Si je tiens celui qui a pondu ce principe je le ****

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    une chaine unicode de type BSTR codé sur 1 octet
    non-sens.

    Ce n'est pas normal que VB veuille une chaîne non-unicode. Normalement, VB utilise des BSTR unicodes, donc en UTF-16/UCS-2.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Problème de requète INSERT INTO avec access
    Par Hipopo dans le forum VB.NET
    Réponses: 7
    Dernier message: 29/03/2010, 12h52
  2. Réponses: 1
    Dernier message: 06/05/2009, 10h33
  3. Réponses: 2
    Dernier message: 07/01/2009, 18h03
  4. Problème pour requête SQL LIKE avec ACCESS
    Par ar.aziz dans le forum VB.NET
    Réponses: 2
    Dernier message: 02/07/2008, 10h53
  5. Problème Syntaxe requête SQL LIKE avec ACCESS
    Par Arnofish dans le forum Accès aux données
    Réponses: 3
    Dernier message: 22/12/2007, 11h57

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