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 :

type csharp vers IntPtr


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut type csharp vers IntPtr
    Bonjour

    Certaines fonctions du wrapper C# de l'API audio FMOD ont besoin de types IntPtr notamment la fonction getInfo de la classe Event.

    C'est la première fois que j'ai affaire à des IntPtr et je sèche complètement...pour être plus précis sur le problème j'ai une erreur FatalExceptionEngineError détectée sur la dernière instruction du code qui suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    string inputStr = "12345";
    GCHandle hstr = GCHandle.Alloc(inputStr);
    IntPtr ptr = GCHandle.ToIntPtr(hstr);
    m_FMODEvent.getInfo(ref index, ref ptr, ref info);
    string outputStr = (string) GCHandle.FromIntPtr(ptr).Target;
    La fonction de cette portion de code est de récupérer le nom de l'objet m_FMODEvent. Pour info voilà le prototype de la fonction FMOD qu'on utilise ici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public RESULT getInfo(ref int index, ref IntPtr name, ref EVENT_INFO info)
    Est ce que je m'y prend mal ?

  2. #2
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    FMOD a déjà une librairie en C# pour utiliser FMOD non ? pas besoin de passer par des trucs bizarre en IntPtr mais simplement il faut utiliser la lib d'interaction en C#.

    Sinon, si ta fonction getInfo c'est bien du PInvoke (DLLImport et tout et tout) elle serait mieux déclarée comme ceci :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    public static extern RESULT getInfo(ref int index, StringBuilder name, ref EVENT_INFO info)

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut
    En fait c'est bien la fonction trouvé dans la lib d'interaction en C#. Je fais comment du coup ?

  4. #4
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Tu es sur qu'il faut utiliser getinfo directement ? (comme je n'utilise plus fmod, je ne sais plus).

    Sinon je vérai bien un truc comme ça :
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    string s = "machin bidule";
                IntPtr p = Marshal.StringToHGlobalAnsi(s);
                /* utiliser p */
                Marshal.FreeHGlobal(p);

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut
    Merci pour ta réponse ça fonctionne super. Pour ceux que ça intéresse voilà le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    string s1 = "machin bidule";
    IntPtr p = Marshal.StringToHGlobalAnsi(s1);
    /* utiliser p */
    m_FMODEvent.getInfo(ref index, ref p, ref info);
    string s2 = string.Empty;
    s2 = Marshal.PtrToStringAnsi(p);
    Parcontre je me demande comment faire avec des objets de n'importe quel type.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut
    J'ai mis la charrue avant les boeufs...le sujet n'est pas complètement résolu car ça ne résout que le problème de conversion des "string".

    J'ai lu sur le net que pour traiter la conversion de "type value" on pouvait utiliser Marshal.PtrToStructure...toutefois j'ai une erreur NullReferenceException lorsque je tente de récupérer la valeur de info.wavebankinfo dans un type managed. Voir le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    string name = string.Empty;
    IntPtr ptr = Marshal.StringToHGlobalAnsi(name);
    m_FMODEvent.getInfo(ref index, ref ptr, ref info);
    FMOD.EVENT_WAVEBANKINFO bankInfo = (FMOD.EVENT_WAVEBANKINFO) Marshal.PtrToStructure(
      info.wavebankinfo, 
      typeof(FMOD.EVENT_WAVEBANKINFO));
    Marshal.Release(ptr);
    Comme tout ça est nouveau pour moi je ne sais pas si c'est la fonction de conversion qui est mal choisi ou si l'objet est vraiment null auquel cas on ne pourra rien faire.

  7. #7
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Si info est nul (ce que tu dois tester dans ton code avant toute manipulation de ce dernier) tu peux rien faire.
    Au fait, la fonction renvoi bien OK comme résultat ?

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut
    J'avais oublié d'initialiser "wavebankinfo" en effet...après correction le debugeur me retourne un AccessViolationException sur l'appel à Marshal.PtrToStructure. Voir code :

    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
    int index = 0;
    FMOD.EVENT_INFO info = new FMOD.EVENT_INFO();
    FMOD.EVENT_WAVEBANKINFO bankinfo = new FMOD.EVENT_WAVEBANKINFO();
     
    IntPtr ptrBankinfo = Marshal.AllocHGlobal(Marshal.SizeOf(bankinfo));
    info.wavebankinfo = ptrBankinfo;
     
    string name = string.Empty;
    IntPtr ptrName = Marshal.StringToHGlobalAnsi(name);
     
    m_FMODEvent.getInfo(ref index, ref ptrName, ref info);
     
    FMOD.EVENT_WAVEBANKINFO bankInfo = (FMOD.EVENT_WAVEBANKINFO) Marshal.PtrToStructure(
      info.wavebankinfo, 
      typeof(FMOD.EVENT_WAVEBANKINFO));
     
    Marshal.Release(ptrName);
    Marshal.Release(ptrBankinfo);
    Est ce que la démarche est bonne ?

  9. #9
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Wow alors là ...
    Mais dit moi il n'y a pas de documentation sur cette fonction (google n'aide pas beaucoup).
    Et la valeur de info.wavebankinfo, si tu la lis directement avec Marshal.Copy et que tu la met dans un byte[], ça fonctionne ou tu as encore un AccessViolation ?

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut
    La doc n'est pas en ligne ça m'a surpris aussi, mais on peut la télécharger gratuitement.

    Oui j'ai un AccessViolation avec Marshal.Copy aussi...je te montre pour voir si je me suis pas trompé.
    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
     
    ...
    int rawsize = Marshal.SizeOf(bankInfo);
    Byte[] rawdatas = new byte[rawsize];
     
    Marshal.Copy(info.wavebankinfo, rawdatas, 0, rawsize);
     
    GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
    IntPtr buffer = handle.AddrOfPinnedObject();
     
    bankInfo = (FMOD.EVENT_WAVEBANKINFO) Marshal.PtrToStructure(
      buffer, 
      typeof(FMOD.EVENT_WAVEBANKINFO));
     
    handle.Free();
    ...

  11. #11
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    ça devrais marcher ... d'une manière ou d'une autre info.wavebankinfo n'est pas valide ...

    elle dit quoi la doc de fmod sur la fonction getinfo ?

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut
    La doc de la structure EVENT_INFO dit ...
    This structure has members that need to be initialized before Event::getInfo is called. Always initialize this structure before calling Event::getInfo!
    Ca nous aide pas du tout, par contre j'ai remarqué ça ...
    wavebankinfo

    [in] Pointer to array FMOD_EVENT_WAVEBANKINFO structures (max size defined by maxwavebanks). FMOD will fill these in with detailed information on each wave bank. Optional.
    J'avais pas vu que c'était un tableau...c'est maintenant corrigé mais le problème n'est pas résolu pour autant. Faudrait voir ce que ça donne en C++, car si ça se trouve c'est les data qui sont pas bonnes.

    Merci pour ton aide.

  13. #13
    Expert éminent
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Points : 8 344
    Points
    8 344
    Par défaut
    Ben ça progresse ...

    Comment tu l'alloues ton array avant de le mettre dans la structure ? (vu que là je ne sais pas trop comment le Marshalling se passe pour ce genre d'array, j'aurai alloué un pointeur faisait taille_élément*nb_éléments, tout mis à zéro, appelé la fonction getInfo et ensuite je me serai battu pour extraire chaque élément de l'array).

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2002
    Messages
    91
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2002
    Messages : 91
    Points : 51
    Points
    51
    Par défaut
    Arf je crois que jme suis fourvoyé...j'avais pas remarqué que le champ wavebankinfo est marqué "in" ça veut dire qu'il ne permet pas de récupérer les info de la banque comme je l'avais imaginé

    Ca aurait au moins permis d'apprendre à utiliser GCHandle et Marshal.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 07/03/2007, 14h27
  2. [C#] Conversion implicite de type object vers int
    Par alexking2005 dans le forum C#
    Réponses: 5
    Dernier message: 02/01/2007, 10h02
  3. Importation de type CSV vers Oracle8i
    Par gamma dans le forum Oracle
    Réponses: 27
    Dernier message: 18/10/2006, 16h44
  4. conversion d'un type Extended vers un string
    Par matterazzo dans le forum Langage
    Réponses: 2
    Dernier message: 28/10/2005, 19h22
  5. Passage du type integer vers varchar sur clé primaire
    Par GMI dans le forum Bases de données
    Réponses: 2
    Dernier message: 07/01/2005, 09h09

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