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 :

Utiliser DLL C avec VB


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut Utiliser DLL C avec VB
    Bonjour,

    Je pense que ce probleme a deja etait aborde plusieurs fois mais apres avoir cherche partout je ne trouve toujours pas la reponse a mon probleme. Je souhaite utiliser un dll detaillant une methode de calcul pour l implementer dans un programme en VB. Je cherche donc a utiliser les fonctions qui se trouvent dans le dll. Le probleme est la correspondance des types.
    Je souhaite pour l instant simplement adapter un simple exemple d utilisation du dll en C dans un environnement VB.
    L exemple est tres simple en 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
    17
    18
    19
    20
    21
    void* p2p ;
    double att[27] ;
    // initialize the PointToPoint module
    p2p = P2P_Create() ;
    if (p2p == NULL)
    {
    ... // error handling : could not create a P2P structure
    }
    // setup the cross-section
    // remember : the origin = point on the road surface below the source
    P2P_Clear(p2p) ; // source foot point (0,0)
    P2P_AddSegment (p2p, 10.0, 0.0, 7) ; // top of embankment
    P2P_AddSegment (p2p, 14.0, -3.0, 5) ; // bottom of embankment
    P2P_AddSegment (p2p, 50.0, -3.0, 4) ; // receiver foot point
    // set the source and receiver heights relative to the local terrain
    // heights at the first and last points of the cross-section
    P2P_SetSourceHeight (p2p, 0.3, 0.0) ;
    P2P_SetReceiverHeight (p2p, 5.0, 0.0) ;
    // calculate the excess attenuation and return the result in “att”
    P2P_GetResult (p2p, att) ;
    // do something with the excess attenuation values...
    Mon code VB est le suivant :

    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
    Private Declare Function Create Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_Create" () As Integer
        Private Declare Function Clear Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_Clear" (ByRef p2p_struct As Integer) As Integer
        Private Declare Function AddSegment Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_AddSegment" (ByRef p2p_struct As Integer, ByVal D As Double, ByVal Z As Double, ByVal impedanceModel As Integer) As Integer
        Private Declare Function SetSourceHeight Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_SetSourceHeight" (ByRef p2p_struct As Integer, ByVal hSource As Double, ByVal delta_hs As Double) As Integer
        Private Declare Function SetReceiverHeight Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_SetReceiverHeight" (ByRef p2p_struct As Integer, ByVal hRec As Double, ByVal delta_hRec As Double) As Integer
        Private Declare Function GetResults Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_GetResults" (ByRef p2p_struct As Integer, ByRef att_dB As Double) As Integer
        Private Declare Function Delete Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_Delete" (ByRef p2p_struct As Integer)
     
        Sub Main()
            Dim p2p As Integer
            p2p = Create()
            Clear(p2p)
            AddSegment(p2p, 10.0, 10.0, 1)
            'AddSegment(p2p, 14.0, -3.0, 5)
            'AddSegment(p2p, 50.0, -3.0, 4)
            'SetSourceHeight(p2p, 0.3, 0.0)
            'SetReceiverHeight(p2p, 5.0, 0.0)
     
            ' Dim att(0 To 27) As Double
     
            'GetResults(p2p, att(0))
     
        End Sub
    J obtiens un message d erreur du type :
    The runtime has encountered a fatal error. The address of the error was at 0x79e784b6, on thread 0xc78. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
    La fonction AddSegment fait planter le tout. Je pense que cela provient du fait que toutes les fonctions attendent un void* et que moi je passe un Integer Byref. Je ne sais pas quoi faire. Si quelqu un peut m aider

    Please....

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Pour commencer, les fonctions doivent avoir la convention d'appel __stdcall (alors que par défaut, c'est __cdecl).

    Ensuite, je pense que tes pointeurs sous forme d'"Integer" doivent être passés par valeur comme le reste...
    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 du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut
    Je ne comprends pas vraiment ta reponse

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    1. Montre la déclaration de tes fonctions C
    2. En VB: ByRef p2p_struct As Integer --> Remplace ByRef par ByVal
    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
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut
    Je n ai pas fais le dll mais je possede le source. Je pense qu il n y a pas de probleme de ce cote. En revanche, j ai un peu changer mon code VB et cela semble marcher sauf la fonction principale.
    Mon nouveau code est:

    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
    Imports System.Runtime.InteropServices
    Module Module1
        Private Declare Function Create Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_Create" () As Integer
        Private Declare Function Clear Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_Clear" (<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal p2p_struct As Object) As Integer
        Private Declare Function AddSegment Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_AddSegment" (<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal p2p_struct As Object, ByVal D As Double, ByVal Z As Double, ByVal impedanceModel As Integer) As Integer
        Private Declare Function SetSourceHeight Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_SetSourceHeight" (<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal p2p_struct As Object, ByVal hSource As Double, ByVal delta_hs As Double) As Integer
        Private Declare Function SetReceiverHeight Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_SetReceiverHeight" (<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal p2p_struct As Object, ByVal hRec As Double, ByVal delta_hRec As Double) As Integer
        Private Declare Function GetResults Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_GetResults" (<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal p2p_struct As Object, ByVal att_dB As Double) As Integer
        Private Declare Function Delete Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_Delete" (<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal p2p_struct As Object) As Integer
     
        Sub Main()
            Dim p2p As Integer
            Dim att(0 To 27) As Double
     
            p2p = Create()
            Clear(p2p)
            AddSegment(p2p, 10.0, 10.0, 1)
            AddSegment(p2p, 14.0, -3.0, 5)
            AddSegment(p2p, 50.0, -3.0, 4)
            SetSourceHeight(p2p, 0.3, 0.0)
            SetReceiverHeight(p2p, 5.0, 0.0)
            'GetResults(p2p, att(0))
            Delete(p2p)
     
            Dim i As Integer
            For i = 0 To att.GetUpperBound(0)
                Console.WriteLine("att(" & i & ") = " & att(i))
            Next i
            Dim ligne As String = Console.In.ReadLine()
        End Sub
     
    End Module
    Si je teste les fonctions addsegment par exemple, elle me retourne bien 1 donc cela semble fonctionner. En revanche la fonction GetResults qui fait tout le calcul me renvoit une erreur:

    Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    Merci

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Impossible de savoir si la DLL est utilisable en VB si tu ne me montres pas le fichier d'en-tête avec la déclaration des fonctions (de plus, tu sembles être en VB.Net, pas VB tout court).
    Si les fonctions n'ont pas la bonne convention d'appel, en VB c'est mort. En VB.Net, il doit y avoir des arguments à rajouter.
    Bon, ce qui précède n'est plus d'actualité, puisque les autres fonctions marchent.
    Peut-on voir le prototype de GetResults() ?
    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.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut
    Pour repondre a la convention d appel, le fichier source ressemble a ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #define  __CALLTYPE     __stdcall
    #define  __EXPORTTYPE   extern "C" __declspec(dllexport)
    Sinon pour le prototype de GetResults:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int P2P_GetResults (void* p2p_struct, double *att)

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Donc, la fonction demande un pointeur sur double et non un double, il faut donc le passer ByRef.
    J'espère qu'il retourne bien UN SEUL double et non un tableau, car je ne suis pas sûr qu'on puisse passer un tableau en VB sans utiliser un SAFEARRAY...
    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.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut
    J ai deja essaye par ref et ca ne marche pas vu qu il attend un tableau. J ai regarde le tutoriel suivant qui explique comment passer un tableau :
    http://rp.developpez.com/vb/tutoriels/dll/#L10

    Je ne sais pas si ca marche. Si tu as une idee..

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Pour ça, il faut modifier la DLL et utiliser un SAFEARRAY.

    Tu peux aussi te faire une DLL qui wrappe l'autre, si tu ne veux/peux pas modifier la DLL originale...
    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.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut
    Je n ai pas envie de faire toucher a la dll. Peux tu m expliquer comment wrapper. Est ce qu il est possible de faire ca avec Visual C++ express ?
    Merci

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Oui, si tu as aussi téléchargé le Platform SDK (disponible gratos séparément).

    En fait, il suffit de faire une DLL (qu'on va appeler DLL2) qui va appeler les fonctions de PointToPoint.dll, et dont la fonction prendra en paramètre un pointeur de SAFEARRAY comme expliqué dans le tutoriel...

    Edit: En fait, si j'en crois le tutoriel, section 10, ce n'est même pas la peine. Tu gardes la DLL existante, et tu lui passes par référence le premier double d'un tableau VB...
    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.

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut
    J ai deja fait ca et ca ne marche pas (dans le tuto ils font passer par valeur et pas pas par adresse, j ai essaye les deux et ca ne marche pas). Si tu as une autre idee..

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Si si, ils font passer par référence: Sous VB6, le passage est ByRef par défaut...

    Peux-tu poster ton code pour l'appel ?
    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.

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 10
    Par défaut
    Mon code est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    (...)
    Private Declare Function GetResults Lib "C:\Documents and Settings\guerini-grossc\My Documents\PointToPoint.dll" Alias "P2P_GetResults" (<MarshalAsAttribute(UnmanagedType.AsAny)> ByVal p2p_struct As Object, ByRef att_dB As Double) As Integer
     
    Dim p2p As Integer
    Dim att(0 To 27) As Double
     
    p2p = Create()
    (...)
    GetResults(p2p, att(0))
    (...)
    J ai toujours le meme message :
    Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
    Merci de ton aide..

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Dans ce cas, je ne peux pas vraiment t'aider.
    Le tuto est pour VB, et toi tu es en VB.Net...

    Vérifie que tu ne dois pas allouer le tableau en premier, ou un truc du genre.
    Pour tester, essaie de lire ou écrire dans le tableau AVANT d'appeler la fonction...
    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. [Débutant] utilisation dll générée avec matlab en C++
    Par 3aychoucha dans le forum MATLAB
    Réponses: 1
    Dernier message: 15/04/2011, 13h16
  2. Réponses: 1
    Dernier message: 06/05/2009, 10h33
  3. Utiliser une DLL Delphi avec C#
    Par h8ciz dans le forum Windows Forms
    Réponses: 3
    Dernier message: 27/09/2007, 16h46
  4. utilisation dll creer avec visual studio
    Par CaptainChoc dans le forum VC++ .NET
    Réponses: 3
    Dernier message: 17/08/2006, 22h07
  5. Utilisation DLL avec java et licence ?
    Par dinver dans le forum Général Java
    Réponses: 4
    Dernier message: 13/04/2006, 21h23

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