Passage de pointeur de structure

Passage de pointeur de structure - C#/.NET managed - Programmation

Marsh Posté le 15-05-2005 à 23:04:13    

yep [:god]
 
dans un élan de masochisme, j'ai décidé d'occuper mon dimanche en recodant mon merveilleux plugin de ma signature en C#
 
l'API de Winamp étant tellement bien foutue, les plugins communiquent avec Winamp par le biais de SendMessage(), vive le progrès [:god]
 
je dois donc jouer avec le P/Invoke et le Marshalling pour convertir tout ce bordel dans les types qui vont bien, du pur bonheur [:itm]
 
voici donc la signature Win32 de SendMessage()

Code :
  1. LRESULT SendMessage(     
  2.     HWND hWnd,
  3.     UINT Msg,
  4.     WPARAM wParam,
  5.     LPARAM lParam
  6. );


et voici ma version pour C# :

Code :
  1. [DllImport("user32.dll",CharSet = CharSet.Auto)]
  2. static extern int SendMessage(
  3.    IntPtr hWnd,
  4.    [MarshalAs(UnmanagedType.U4)] int Msg,
  5.    IntPtr wParam,
  6.    IntPtr lParam);


 
sans oublier une jolie structure du SDK de Winamp, 100% moderne [:god]

Code :
  1. typedef struct {
  2.   char *filename;
  3.   char *metadata;
  4.   char *ret;
  5.   int retlen;
  6. } extendedFileInfoStruct;


et ma version managée

Code :
  1. [StructLayout(LayoutKind.Sequential,CharSet = CharSet.Ansi)]
  2. public struct extendedFileInfoStruct
  3. {
  4.    public string filename;
  5.    public string metadata;
  6.    public StringBuilder ret;
  7.    uint retlen;
  8. }


ou est le problème ? très simple ! [:god]
après avoir rempli cette magnifique structure, je dois passer un pointeur vers cette structure à SendMessage() en wParam, et c'est là que je bloque !
 
si je fais ça (efi est une instance de la structure) :

Code :
  1. SendMessage(pluginWindow, WM_WA_IPC, ref efi, (IntPtr)IPC_GET_EXTENDED_FILE_INFO);


j'ai ce joli message :

Citation :


Argument '3' : impossible de convertir de 'ref Plugin.mainApp.extendedFileInfoStruct' en 'System.IntPtr'


 
par contre, si je change le type du paramètre 3 de ma fonction SendMessage() managée comme ceci :

Code :
  1. static extern int SendMessage(
  2.    IntPtr hWnd,
  3.    [MarshalAs(UnmanagedType.U4)] int Msg,
  4.    ref extendedFileInfoStruct wParam,
  5.    IntPtr lParam);


ça marche nickel [:god]
 
mais bon, c'est une solution à la con, car si je devais utiliser SendMessage plusieurs fois dans mon programme, je l'aurais dans l'os !
 
l'idéal serait de passer en mode unsafe, et de lui passer l'adresse de la structure, mais j'aimerais savoir si y'a pas un moyen plus propre et moins bourrin
 
vala [:god]


Message édité par Harkonnen le 15-05-2005 à 23:06:29

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 15-05-2005 à 23:04:13   

Reply

Marsh Posté le 15-05-2005 à 23:14:46    

je te lis pas mais je te dis que ce bordel d'unsage c'est vraiment une daube. Sous windows, si tous tes produits utilise VC++ ça va, mais dans le reste du monde, ça marche pas les structures sont jamais alignées pareilles et t'es obligées de dupliquer tout le code des déclaration de struct ... c'est naz, mieux vaut une API C comme pour python ou rubyu

Reply

Marsh Posté le 15-05-2005 à 23:17:09    

c'est bien pour ça que je préfererais éviter :/
au pire, je garderais la déclaration spécifique de SendMessage :spamafote:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 15-05-2005 à 23:18:22    

ah ben apparemment y'a pas que moi qui bloque avec ça [:dawa]
http://groups.google.fr/group/micr [...] 937088bcec


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 15-05-2005 à 23:20:56    

moi par exemple j'ai
 
struct Foo;
 
void Foo_fill(struct Foo* buf);
 
qui remplit une structure.
 
C'est IMPOSSIBLE d'accéder aux champs de struct Foo en unsafe vu que personne te garantis que la disposition des membres sera pareil. Bref, je me retrouves à faire un getter par membre et j'arrondis les angles en mettant des types de retour que C# va bouffer. C'est pourri, c'est une énorme perte de temps.

Reply

Marsh Posté le 15-05-2005 à 23:44:45    

d'ou l'intéret de l'attribut StructLayoutAttribute


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 15-05-2005 à 23:47:48    

mmm, je me demande si ceci ne ferait pas l'affaire [:figti]
http://msdn.microsoft.com/library/ [...] rtopic.asp


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 16-05-2005 à 00:00:50    

Harkonnen a écrit :

d'ou l'intéret de l'attribut StructLayoutAttribute


et tu fais comment pour le renseigner ? t'as une idée à priori de comment ton compilateur C va faire son truc ?

Reply

Marsh Posté le 16-05-2005 à 09:20:54    

Taz a écrit :

et tu fais comment pour le renseigner ? t'as une idée à priori de comment ton compilateur C va faire son truc ?


non, mais c'est une remarque que j'envoyais comme ça sans rapport avec le mode unsafe. c'est bien d'avoir pensé aux LayoutKind pour pouvoir spécifier l'alignement en mémoire des membres en cas de P/Invoke :spamafote:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 16-05-2005 à 09:21:50    

bon, je suis très flatté de la présence de Taz sur ce maigre topic, mais on dirait quand même que pour le moment c'est un beau bide [:god]


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 16-05-2005 à 09:21:50   

Reply

Marsh Posté le 16-05-2005 à 10:36:25    

Harkonnen a écrit :

non, mais c'est une remarque que j'envoyais comme ça sans rapport avec le mode unsafe. c'est bien d'avoir pensé aux LayoutKind pour pouvoir spécifier l'alignement en mémoire des membres en cas de P/Invoke :spamafote:


super, si la disposition d'une structure c'était aussi simple ... je te fais pas un tableau, mais entre X86 et sparc64, c'est un peu différent  :sweat:

Reply

Marsh Posté le 16-05-2005 à 14:33:06    

bon, finalement j'ai trouvé un site sympa : http://www.pinvoke.net
 
et apparemment, il semble qu'il soit possible de surcharger les fonctions Win32 importées, ce que je ne savais pas du tout. ça me permet de déclarer plusieurs signatures de SendMessage()
 
http://www.pinvoke.net/default.asp [...] ssage.html


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-05-2005 à 13:15:19    

bon, finalement je vais passer en unsafe pour une raison très simple : je passe en paramètre un pointeur vers ma structure. or, Garbage Collector oblige, je dois figer cette structure en mémoire sinon ça va être la fête de l'huitre quand le GC se réveillera et bougera mes références :/
"fixed" roulaize
 
=> je posterai le code quand j'aurais trouvé


Message édité par Harkonnen le 17-05-2005 à 13:15:46

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-05-2005 à 13:20:43    

moi je comprends toujours pas comment faire facilement pour récupérer la définition d'une structure telle qu'elle est dans son .h et être sur que ton compilateur C# va la construire comme ton compilateur C ...

Reply

Marsh Posté le 17-05-2005 à 13:41:53    

et si tu définis les offsets à la main via LayoutKind.Explicit ?
un article assez clair (orienté Win32, mais ça peut t'aider quand même)
http://msdn.microsoft.com/msdnmag/issues/04/10/NET/


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 17-05-2005 à 14:01:49    

moi je code sur sparc32 avec gcc-2.95, tu crois que j'ai une idée de la disposition sur amd64 avec gcc-4.0 ?

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed