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

Windows Forms Discussion :

ImportDLL paramètre structure


Sujet :

Windows Forms

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut ImportDLL paramètre structure
    Bonjour à tous,

    tout d'abord meilleurs voeux pour cette année 2012.

    Je rencontre des difficultés pour implémenter un DLL dans une application windows form en c#.

    La DLL contient un ensemble de fonction écrite en c/c++ dont je ne suis pas l'auteur.

    Je tente d'exploiter ce DLL en c#. J'ai pour le moment réussi à exploiter une fonction dont le paramètre retour était un string simplement.

    voici comment j'ai procédé:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    using System.Runtime.InteropServices;
     
    [DllImport("lib.dll", CharSet = CharSet.Ansi,
            CallingConvention = CallingConvention.StdCall, EntryPoint = "version")]
            public static extern string version();
     
    private void button3_Click(object sender, EventArgs e)
            {
               label1.Text = "Version: "+ version();
            }
    Cela fonctionne très bien.

    Maintenant je rencontre une difficulté pour déclarer une fonction dont les paramètres utiles et retour sont des structures, voire des pointeurs de structure qui contiennent des char et autre variables.

    J'ai un peu cherché sur le net mais je n'ai rien trouvé correspondant vraiment à mon cas. IntPtr ?

    Est ce que quelqu'un pourrait m'expliquer la procédure pour déclarer correctement ce genre de fonction en langage c# ?

    merci d'avance pour votre aide.

  2. #2
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Salut,
    Si tu ne nous donne pas la signature de la fonction et des structures on ne risque pas de pouvoir t'aider.
    Sinon, regarde comment c'est fait pour les API Win32, il y a plein d'exemple sur www.pinvoke.net.
    On a par exemple CreateDIBitmap, une fonction qui prend en paramètre un pointeur sur une structure BITMAPINFOHEADER.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut
    Merci pour ta réponse rapide.

    je comptais justement éditer mon post avec un exemple de fonction en question.

    Voici un exemple de fonction de la librairie:

    => nfc_device_t* nfc_connect (nfc_device_desc_t * pndd)

    nfc_device_desc_t Struct Reference :

    char acDevice [DEVICE_NAME_LENGTH]
    char * pcDriver
    char acPort [DEVICE_PORT_LENGTH]
    uint32_t uiSpeed
    uint32_t uiBusIndex

    nfc_device_t Struct Reference :

    struct nfc_driver_t * driver
    char acName [DEVICE_NAME_LENGTH]
    bool bCrc
    bool bPar
    bool bEasyFraming
    bool bAutoIso14443_4
    byte_t btSupportByte
    int iLastError

    nfc_connect est un exemple de fonction que je dois déclarer dans mon DLL import.

  4. #4
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Il manque la structure nfc_driver_t, ainsi que la valeur des #define DEVICE_NAME_LENGTH et DEVICE_PORT_LENGTH.

    Avec ce que tu donnes actuellement, le pinvoke doit être quelque chose comme ça :
    Code c# : 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
     
    [DllImport("lib.dll", CharSet=CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.LPStruct)]
    public static extern nfc_device_t nfc_connect([In, MarshalAs(UnmanagedType.LPStruct)]nfc_device_desc_t pndd);
     
    [StructLayout(LayoutKind.Sequential)]
    struct nfc_device_desc_t
    {
    	[MarshalAs(UnmanagedType.ByValTStr, SizeConst=DEVICE_NAME_LENGTH)]
    	string acDevice;
    	[MarshalAs(UnmanagedType.LPStr)]
    	string pcDriver;
    	[MarshalAs(UnmanagedType.ByValTStr, SizeConst=DEVICE_PORT_LENGTH])]
    	string acPort;
    	UInt32 uiSpeed;
    	UInt32 uiBusIndex;
    }
     
    [StructLayout(LayoutKind.Sequential)]
    struct nfc_device_t
    {
    	nfc_driver_t driver;
    	[MarshalAs(UnmanagedType.ByValTStr, SizeConst=DEVICE_NAME_LENGTH)]
    	string acName;
    	bool bCrc;
    	bool bPar;
    	bool bEasyFraming;
    	bool bAutoIso14443_4;
    	byte btSupportByte;
    	int iLastError;
    }

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut
    Le code est impressionnant. je n'aurai jamais trouvé ça moi même.

    voici les paramètres manquant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    typedef struct {
    const struct nfc_driver_t *driver;
    void* driver_data;
    void* chip_data;
     
    char    acName[DEVICE_NAME_LENGTH];
    bool    bCrc;
    bool    bPar;
    bool    bEasyFraming;
    bool    bAutoIso14443_4;
    byte_t  btSupportByte;
    int     iLastError;
    } nfc_device_t;
    et les deux defines :

    00037 # define DEVICE_NAME_LENGTH 256
    00038 # define DEVICE_PORT_LENGTH 64

    Je devrai opérer de la même manière pour chaque fonctions du DLL ?

    Si il manque encore des paramètres, j'aurai plus de chance de te donner le lien qui fourni la documentation de la librairie.

    Merci en tout cas pour ton aide. J'y vois déjà un peu plus clair.

  6. #6
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par GGelec Voir le message
    Le code est impressionnant. je n'aurai jamais trouvé ça moi même.

    voici les paramètres manquant :
    .
    Non, il manque toujours la définiton de nfc_driver_t.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut
    Hum je cherche après cette définition.

    Voici le lien de la documentation de la libraire (dans le cas où vous le trouvez plus rapidement).

    http://code.google.com/p/libnfc/down...1.zip&can=2&q=

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut
    je pense avoir trouvé ...

    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
    struct nfc_driver_t {
    00128   const char *name;
    00129   bool (*probe)(nfc_device_desc_t pnddDevices[], size_t szDevices, size_t * pszDeviceFound);
    00130   nfc_device_t * (*connect)(const nfc_device_desc_t * pndd);
    00131   void (*disconnect)(nfc_device_t * pnd);
    00132   const char *(*strerror)(const nfc_device_t * pnd);
    00133 
    00134   bool (*initiator_init) (nfc_device_t * pnd);
    00135   bool (*initiator_select_passive_target) (nfc_device_t * pnd,  const nfc_modulation_t nm, const byte_t * pbtInitData, const size_t szInitData, nfc_target_t * pnt);
    00136   bool (*initiator_poll_target) (nfc_device_t * pnd, const nfc_modulation_t * pnmModulations, const size_t szModulations, const uint8_t uiPollNr, const uint8_t btPeriod, nfc_target_t * pnt);
    00137   bool (*initiator_select_dep_target) (nfc_device_t * pnd, const nfc_dep_mode_t ndm, const nfc_baud_rate_t nbr, const nfc_dep_info_t * pndiInitiator, nfc_target_t * pnt);
    00138   bool (*initiator_deselect_target) (nfc_device_t * pnd);
    00139   bool (*initiator_transceive_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
    00140   bool (*initiator_transceive_bits) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
    00141   bool (*initiator_transceive_bytes_timed) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t * pszRx, uint32_t * cycles);
    00142   bool (*initiator_transceive_bits_timed) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar, uint32_t * cycles);
    00143 
    00144   bool (*target_init) (nfc_device_t * pnd, nfc_target_t * pnt, byte_t * pbtRx, size_t * pszRx);
    00145   bool (*target_send_bytes) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, struct timeval *timeout);
    00146   bool (*target_receive_bytes) (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRx, struct timeval *timeout);
    00147   bool (*target_send_bits) (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTxBits, const byte_t * pbtTxPar);
    00148   bool (*target_receive_bits) (nfc_device_t * pnd, byte_t * pbtRx, size_t * pszRxBits, byte_t * pbtRxPar);
    00149 
    00150   bool (*configure) (nfc_device_t * pnd, const nfc_device_option_t ndo, const bool bEnable);
    00151 
    00152   bool (*abort_command) (nfc_device_t * pnd);
    00153   bool (*idle) (nfc_device_t * pnd);
    00154 };

  9. #9
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par GGelec Voir le message
    je pense avoir trouvé ...
    Euh .... oui ....
    Mais là, je pense que les choses vont se compliquer très sérieusement.

    A mon avis, il serait préférable d'écrire un wrapper C++/CLI de cette librairie que tu vas utiliser dans ton programme client plutot que tenter de l'appeler directement depuis C#/Net.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par Bluedeep Voir le message
    Euh .... oui ....
    Mais là, je pense que les choses vont se compliquer très sérieusement.

    A mon avis, il serait préférable d'écrire un wrapper C++/CLI de cette librairie que tu vas utiliser dans ton programme client plutot que tenter de l'appeler directement depuis C#/Net.
    je me rend bien compte maintenant de la difficulté du procédé. Ça prend beaucoup trop de temps.

    Honnêtement, je n'ai pas étudié la meilleur manière d'exploiter cette librairie.

    Si selon vous, écrire un wrapper c++/cli représente la meilleur solution pour utiliser cette libraire en c# alors je vais essayer de le faire.

    Encore faut-il que je me renseigne sur la réalisation de ce wrapper en question.

    Peut-être que la réalisation d'un application en c++ exploitant directement les fichier .c et .h pourrait être encore plus facile?

    je suis ouvert à toute suggestion.

  11. #11
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par GGelec Voir le message
    Peut-être que la réalisation d'un application en c++ exploitant directement les fichier .c et .h pourrait être encore plus facile?

    je suis ouvert à toute suggestion.
    Si tu fais tout en C++, tu te prive de .net pour le reste de l'appli : c'est à toi de voir. C'est pourquoi je te suggère un wrapper C++/CLI (en gros, un code qui sera C++ non managé d'un coté, C++ managé de l'autre, donc exploitable par une autre appli.Net quel que soit le langage) qu'exploitera ton appli.

    A la réflexion, et sauf erreur de ma part (n'ayant plus sérieusement touché au C depuis de longues années), je soupçonne ta struct avec les pointeurs de fonction de n'être même pas exploitable via P/Invoke (mais je peux me tromper sur ce point).

    Donc pour moi, la meilleure solution ici réside dans le développement d'un wrapper.

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  12. #12
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut
    je vais me renseigner sur la réalisation d'un wrapper.

    Au pire, si je ne m'en sort pas, je viendrai poster un nouveau post.

    Merci beaucoup pour ton analyse Bluedeep

  13. #13
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    J'arrive un peu après la guerre, ... enfin, je reviens...
    Cette dernière structure devient vraiment plus la misère, elle est bourrée de pointeurs sur fonction.
    Cependant, c'est peut être encore jouable. Les pointeurs fonctions sont "marshalés" en tant que delegate. Tu dois donc avoir moyen d'écrire des delegates qui correspondent aux pointeurs de fonctions puis faire une structure avec des membres typés par ces delegates.
    La flemme de m'essayer à la conversion ce soir, à cette heure...

    Sinon le wrapper en C++/CLI est une assez bonne option. Il te faut écrire des classes C++/CLI qui encapsule ces structures. Elles sont donc manipulée en C++ (donc aucune conversion à faire) et tu exposes au .Net ce que tu veux (tes classes C++/CLI). Une fois le wrapper fait, tu pourra utiliser ce wrapper dans du C#.

  14. #14
    Inactif  
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Janvier 2007
    Messages
    6 604
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC

    Informations forums :
    Inscription : Janvier 2007
    Messages : 6 604
    Points : 13 314
    Points
    13 314
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Cependant, c'est peut être encore jouable. Les pointeurs fonctions sont "marshalés" en tant que delegate.
    En effet, je n'avais jamais "repéré" la valeur UnmanagedType.FunctionPtr.

    Donc, en effet, c'est possible qu'il traite le tout via P/Invoke, mais je pense que a priori ce sera plus simple de créer un wrapper; sauf si GGelec ne connait pas le C++, auquel cas vaut mieux perséverer dans le P/Invoke, même si le résultat risque fort d'être un vapocraqueur dans ce cas

    Je ne réponds pas aux questions techniques par MP ! Le forum est là pour ça...


    Une réponse vous a aidé ? utiliser le bouton

    "L’ennui dans ce monde, c’est que les idiots sont sûrs d’eux et les gens sensés pleins de doutes". B. Russel

  15. #15
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

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

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Oui c'est sur qu'en PInvoke ca va être lourd ... Vu la tronche de la dernière structure, il faut implémenter pleins de delegates qui prennent en paramètres des pointeurs et autres structures, résultat va y avoir des MarshalAs(...) partout. En prime il va se retrouver avec des objets alloués dans le monde natif qu'il va falloir delete depuis le monde managé ce qui va être saoulant à gérer.

    C'est aussi simple de faire un wrapper c++/cli à mon avis aussi. Mais bon, quand on connais pas le c++, faire un wrapper c++/cli c'est loin d'être évident.

  16. #16
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2010
    Messages : 66
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par ctxnop Voir le message
    Oui c'est sur qu'en PInvoke ca va être lourd ... Vu la tronche de la dernière structure, il faut implémenter pleins de delegates qui prennent en paramètres des pointeurs et autres structures, résultat va y avoir des MarshalAs(...) partout. En prime il va se retrouver avec des objets alloués dans le monde natif qu'il va falloir delete depuis le monde managé ce qui va être saoulant à gérer.

    C'est aussi simple de faire un wrapper c++/cli à mon avis aussi. Mais bon, quand on connais pas le c++, faire un wrapper c++/cli c'est loin d'être évident.
    Bonsoir,

    je pense avoir la solution après des heures de recherche.

    Je suis parvenu à trouver comment on peut appeler des fonctions à partir du DLL sans wrapper.

    J'ai trouvé une bonne partie sur le net. Pour l'instant cela fonctionne bien mais pour un DLL dont la version est antérieure à mon DLL actuel. J'essai donc de réécrire l'ensemble du code c# pour exploiter mon DLL.

    Pour le nfc_connect on importe le code de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    [DllImport("nfc.dll")]
        private static extern IntPtr nfc_connect(ref nfc_device_desc_t pndd);
    avec la structure requise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    /// <summary>
      /// Length 272
      /// </summary>
      [StructLayout(LayoutKind.Sequential)]
      public struct nfc_device_desc_t {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
        public string acDevice;
        public IntPtr pcDriver;
        public IntPtr pcPort;
        public uint uiSpeed;
        public uint uiBusIndex;
      }
    Il s'agit donc du code implémenté pour l'ancienne DLL et voici comment il est appelé dans le code en c# :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public nfc_device_t connect(nfc_device_desc_t pndd) {
          disconnect();
          _handle = nfc_connect(ref pndd);
          nfc_device_t ndRet = (nfc_device_t)Marshal.PtrToStructure(_handle, typeof(nfc_device_t));
          return ndRet;
        }
    L'ensemble fonctionne bien.

    Dans les nouvelles librairies, il y a quelques modifications au niveau de la structure que j'ai changé suivant le source de la librarie, pour faire mon nfc_connect, je dois utiliser nfc_list_devices dont voici la structure utilisée/modifiée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [StructLayout(LayoutKind.Sequential)]
            public struct nfc_device_desc_t
            {
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
                public string acDevice;
                public IntPtr pcDriver;
                [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] 
                public string acPort;
                public uint uiSpeed;
                public uint uiBusIndex;
            }
    les paramètres requis par la fonction reste identique, j'ai donc implémenter le même code mais avec un allocation de mémoire différente, on passe de 272 à 332 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [DllImport("libnfc.dll")]
            private static extern void nfc_list_devices(IntPtr pnddDevices, uint szDevices, ref uint pszDeviceFound);
            public nfc_device_desc_t[] list_devices(ref uint uDev)
            {
                IntPtr ip = Marshal.AllocHGlobal(/*272*/332 * 16);
                LibNFC.nfc_list_devices(ip, 1, ref uDev);
                nfc_device_desc_t[] device = new nfc_device_desc_t[16];
                for (uint i = 0; i < uDev; i++)
                {
                    device[i] = (nfc_device_desc_t)Marshal.PtrToStructure(new IntPtr(ip.ToInt32() + (332 * i)), typeof(nfc_device_desc_t));
                }
                Marshal.FreeHGlobal(ip);
                return device;
            }
    mais je rencontre une erreur du type PInvokeStackImbalance:

    Un appel à la fonction PInvoke 'NFCidd!NFCidd.LibNFC::nfc_list_devices'
    a déséquilibré la pile.
    Cela peut se produire, car la signature PInvoke managée ne correspond pas à la signature
    cible non managée.
    Vérifiez que la convention d'appel et les paramètres de la signature PInvoke
    correspondent à la signature non managée cible.
    Cette erreur pointe sur la ligne suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LibNFC.nfc_list_devices(ip, 1, ref uDev);
    Au final, je ne suis pas très sur d'avoir très bien compris le mécanisme mit en place et je ne demande qu'à comprendre car par la suite je devrai implémenter de nouvelle fonction.

    Si vous pouviez m'aider ça serait super.

    Merci déjà pour votre aide jusqu'à présent

    GGelec

Discussions similaires

  1. WSDL et paramètres "structurés" tableau/table de hachage
    Par _-Sky-_ dans le forum Services Web
    Réponses: 1
    Dernier message: 17/04/2009, 13h36
  2. structure en paramètre d'une fonction
    Par Tex-Twil dans le forum C
    Réponses: 6
    Dernier message: 29/03/2006, 21h42
  3. sequence de structure en paramétre de methode.
    Par lessecs dans le forum CORBA
    Réponses: 3
    Dernier message: 11/02/2006, 21h15
  4. Réponses: 10
    Dernier message: 04/01/2006, 16h57
  5. Réponses: 10
    Dernier message: 17/12/2004, 13h36

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