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

VBA Access Discussion :

Marshalling en vba access


Sujet :

VBA Access

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 63
    Points : 37
    Points
    37
    Par défaut Marshalling en vba access
    Bonjour,

    Je développe actuellement une base de données sous access, et je souhaiterai faire le lien avec une DLL que l'on ma donné, codée en C++ et qui fonctionne très bien en vb2

    Mon problème est que dans l'appel d'une fonction de ma DLL, j'ai un type WCHAR, il faudrait que je fasse du marshalling , le soucis c'est que je ne trouves pas le marshalling en vba, seulement en vb

    en Vb ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Private Declare Sub Generate Lib "pxweb.dll" (ByVal web1 As Integer, _
                <MarshalAsAttribute(UnmanagedType.LPWStr)> ByRef web2 As String)
    le soucis c'est que la fonction MarshalAsAttribute n'existe pas en VBA

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Points : 7 759
    Points
    7 759
    Par défaut
    Bonjour,

    Je ne sais pas si c'est la méthode appropriée mais voila comment je fais dans VBA.

    Prenons par exemple la fonction API GetUserName qui existe dans les deux versions, ANSI et UNICODE.
    Déclaration:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    ' Déclaration ANSI
    Declare Function apiGetUserName_ANSI Lib "Advapi32" Alias "GetUserNameA" _
                    (ByVal UserName As String, ByRef lgSize As Long) As Boolean
     
    ' Déclaration Unicode
    Declare Function apiGetUserName_Unicode Lib "Advapi32" Alias "GetUserNameW" _
                    (ByVal UserName As String, ByRef lgSize As Long) As Boolean
    Les buffers de caractères sont déclarés par valeur (ByVal) et de type String. VBA transmettra en réalité un pointeur.
    On ne sait pas différencier entre ANSI (CHAR) et UNICODE (WCHAR) au niveau de la déclaration. La marshalling n'exite donc pas en VBA.

    Utilisation dans du code VBA des deux fonctions ci-dessus:
    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
    Sub TestGetUserName()
        Dim sBuffer As String
        Dim lgBufferSize As Long
        Dim sUserName_ANSI As String
        Dim sUserName_Unicode As String
     
        ' api ANSI
        lgBufferSize = 200
        sBuffer = String(lgBufferSize, vbNullChar)
        If (apiGetUserName_ANSI(sBuffer, lgBufferSize)) Then
           sUserName_ANSI = Left(sBuffer, lgBufferSize - 1)
           MsgBox sUserName_ANSI, vbInformation, "apiGetUserName_ANSI"
        End If
     
        ' api UNICODE
        lgBufferSize = 200 * 2
        sBuffer = String(lgBufferSize, vbNullChar)
        If (apiGetUserName_Unicode(sBuffer, lgBufferSize)) Then
            ' rogner le buffer
            sBuffer = Left(sBuffer, (lgBufferSize - 1) * 2)
            ' convertir Unicode -> Ansi
            sUserName_Unicode = StrConv(sBuffer, vbFromUnicode)
            MsgBox sUserName_Unicode, vbInformation, "apiGetUserName_Unicode"
        End If
     
    End Sub
    Ce qui change quand j'utilise la fonction unicode (caractères WCHAR), c'est que je double la taille de mon buffer et que j'utilise la fonction StrConv pour convertir mon buffer.

    A+

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 63
    Points : 37
    Points
    37
    Par défaut
    en faite je pense que mon problème vient plus du faite que c'est un WCHAR*
    J'ai l'impression qu'il n'aime pas la sub avec un pointeur :/

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 63
    Points : 37
    Points
    37
    Par défaut
    Je suis passé sur un DLL codé en C, le seul problème vient du marshalling pour la valeur de retour, il n'arrive pas a récupérer mon WCHAR ...

  5. #5
    Expert éminent
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Points : 7 759
    Points
    7 759
    Par défaut
    Bonsoir,

    Il importe peu sur quoi pointe le pointeur.
    Ça sera toujours un entier, qu'il pointe sur un WCHAR, sur un CHAR, ou sur n'importe quoi d'autre.

    Voir Passer une chaîne de caractères par valeur .
    Le titre ne correspond pas à la réalité car c'est bien un pointeur que VBA passe à la fonction C.
    Par contre dans la déclaration VBA (Private Declare Sub ....) l'argument est déclaré "par valeur" (ByVal).
    C'est valable pour un LPSTR comme pour un LPWTR.
    En revanche VBA ne sait gérer que des CHAR. D'où mon recours à StrConv.

    Si ma fonction DLL attend un LPWSTR:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Dim sMaChaine As String, sMonBuffer As String
     
    sMaChaine = "Hello"
    sMonBuffer = StrConv(sMaChaine, vbUnicode)
    LaFonctionDll sMonBuffer
    Si ma fonction DLL retourne un LPWSTR:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Dim sMaChaine As String, sMonBuffer As String
     
    sMonBuffer= String(512, vbNullChar) ' initialise buffer de 512 octets
    LaFonctionDll sMonBuffer
    sMaChaine= StrConv(sMonBuffer, vbFromUnicode)
    L'adaptation se fait côté code VBA par le développeur, car on ne sait pas le faire côté déclaration en VBA.

    A+

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2014
    Messages
    63
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2014
    Messages : 63
    Points : 37
    Points
    37
    Par défaut
    le probleme c'est que je ne peux pas faire un strconv ni autre chose, lorsque access passe dans ma fonction qui appel la DLL, j'ai un APPCRASH de msaccess.exe

  7. #7
    Expert éminent
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Points : 7 759
    Points
    7 759
    Par défaut
    Bonsoir,

    Je me demande si la fonction de la dll attend un pointeur sur une chaîne de caractères (LPWSTR, ce dont je parle depuis le début)
    ou bien un pointeur sur un pointeur chaîne de caractères (LPWSTR*).

    Quelle est la signature de la fonction c/c++ ?

    Generate(short webl, LPWSTR web2) (cas 1)
    ou
    Generate(short webl, LPWSTR *web2) (cas 2) ?

    Pour le cas 1, on est dans ce cas de figure : Passer une chaîne de caractères par valeur
    Private Declare Sub Generate Lib "pxweb.dll" (ByVal web1 As Integer, ByVal web2 As String).
    (! Il y a un PtrSafe à mettre quelque part pour VBA7)

    Pour le cas 2, on est dans ce cas de figure : Passer une chaîne de caractères par référence
    Private Declare Sub Generate Lib "pxweb.dll" (ByVal web1 As Integer, ByRef web2 As String).
    (! Il y a un PtrSafe à mettre quelque part pour VBA7)

    A+

Discussions similaires

  1. Réponses: 4
    Dernier message: 16/06/2005, 15h37
  2. Réponses: 4
    Dernier message: 19/05/2005, 11h51
  3. Réponses: 4
    Dernier message: 16/04/2005, 16h54
  4. [VBA] Access-> Excel Format de cellule
    Par toflofr dans le forum VBA Access
    Réponses: 19
    Dernier message: 31/07/2003, 14h26

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