[C#/C] Dllimport et pointeur de fonction

Dllimport et pointeur de fonction [C#/C] - C#/.NET managed - Programmation

Marsh Posté le 03-01-2012 à 18:43:57    

Bonjour,
 
Je dispose d'une bibliotheque C à laquelle je souhaite accéder.
Dans cette bibliothèque se trouvent un certain nombre de fonctions qui ont toutes, peu ou prou, la même signature.
exemple :  

Code :
  1. extern "C" __declspec(dllimport) int CardDetect(bool Debug, void (*)(char *Data, int Len));

 
 
Comme vous pouvez le voir, le dernier paramètre est un pointeur sur fonction qui renvoie des informations à afficher éventuellement sous la forme d'une chaine de caractère.
 
J'essaie donc d'accéder à ces fonctions depuis mon code C# mais je coince sur le deuxième paramétre.
 
J'ai essayé avec un delegate et avec un IntPtr mais rien n'y fait.
 
Auriez-vous une idée de la manière de faire pour accéder à ce type de fonctions, car là, je sèche vraiment.
 
ex de code qui ne marche pas (déséquilibre de la pile...) :
 

Code :
  1. class Program
  2. {
  3.  public delegate void MyCallback();
  4.  [DllImport("DriverDll.dll",EntryPoint = "_CardDetect" )]
  5.  static extern long CardDetect(bool Debug, MyCallback callback);
  6.  static void Main(string[] args)
  7.  {
  8.   var ptr = IntPtr.Zero;
  9.   Console.WriteLine(CardDetect(false,null));
  10.   //Console.WriteLine(CardDetect(false,ref ptr));
  11.  }
  12. }


 
Merci d'avance.
 
v.


Message édité par vonm le 03-01-2012 à 18:45:38
Reply

Marsh Posté le 03-01-2012 à 18:43:57   

Reply

Marsh Posté le 04-01-2012 à 10:46:47    

Merci pour ta réponse.
Je t’avoue que ça me parait un peu brumeux mais je ne suis pas sur que cela s'adapte a ce que je veux faire.
 
C'est d'autant plus vrai que ce code s'adapte a du .net 1.1 et moi je suis en V4.
 
v.

Reply

Marsh Posté le 04-01-2012 à 11:09:59    

Aucun changement.
 
Mon nouveau code :

Code :
  1. public delegate void MyCallback(string Data, int Len);
  2.  [DllImport("DriverDll.dll",EntryPoint = "_CardDetect" )]
  3.  static extern long CardDetect(bool Debug, MyCallback callback);
  4.  static void Main(string[] args)
  5.  {
  6.   Console.WriteLine(CardDetect(false,null));
  7.  }


 
et le résultat :
 
PInvokeStackImbalance was detected
Message: Un appel à la fonction PInvoke 'TestLectureCarte!TestLectureCarte.Program::CardDetect' 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.
 
v.

Reply

Marsh Posté le 04-01-2012 à 16:04:55    


 
Yahoooo...
 
Ca a l'air de marcher.
 
Merci a tous.
 
v.

Reply

Marsh Posté le 06-01-2012 à 11:50:49    

Re,
 
finalement, j'ai voulu aller plus loin et ca ne marche plus.
Le pointeur de fonction C est un moyen d'afficher un texte en provenance de ma dll pour la trace de ce qui se passe.
Je me suis donc dit que ca pouvait etre interessant d'utiliser.
 
J'ai donc utilisé le code suivant :
 

Code :
  1. class Program
  2. {
  3.  public delegate void DisplayDelegate(string Data, int Len);
  4.  [DllImport("DriverDll.dll", EntryPoint = "_CardDetect", CallingConvention = CallingConvention.Cdecl)]
  5.  static extern int CardDetect(bool Debug, DisplayDelegate callback);
  6.  [DllImport("DriverDll.dll", EntryPoint = "_CardDriver", CallingConvention = CallingConvention.Cdecl)]
  7.  static extern int CardDriver(bool Debug, DisplayDelegate callback);
  8.  static void Main(string[] args)
  9.  {
  10.   DisplayDelegate callback = Display;
  11.   int ret = CardDetect(false, callback);
  12.   Console.WriteLine(ret);
  13.  }
  14.  static void Display(string data, int Len)
  15.  {
  16.   Console.WriteLine(data);
  17.  }
  18. }


 
et lorsque je l'execute, je passe bien dans la methode Display avec la bonne chaine de caractere mais en ressortant, je recupere l'erreur suivante :
 
System.AccessViolationException was unhandled
  Message=Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.
  Source=TestLectureCarte
  StackTrace:
       à TestLectureCarte.Program.CardDetect(Boolean Debug, DisplayDelegate callback)
       à TestLectureCarte.Program.Main(String[] args) dans D:\VM_DATA\Visual Studio 2010\Projects\TestLectureCarte\TestLectureCarte\Program.cs:ligne 24
       à System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       à System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       à Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       à System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       à System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       à System.Threading.ThreadHelper.ThreadStart()
  InnerException:  
 
alors que si je passe null à la place du delegate,tout se passe bien.
 
Une idée ?
 
v.

Reply

Marsh Posté le 06-01-2012 à 12:20:47    


 
Non je ne pense pas que ce soit ça (encore que) !
 
Le deuxieme parametre de mes fonctions C est un pointeur de fonction avec parametres.
Si je lui passe un delegate qui a le meme propotype, tout se passe bien.
 
Le probleme survient quand je souhaite utiliser les donnees remontees.
C'est bien le principe de mon delegate que de faire le pont entre son appel et la methode reelle (C#) qui va traiter ces parametres non ?
 
Je suis d'autant plus perplexe que dans mon exemple, la methode Display est bien appelée avec les bonnes valeurs de parametres.
Par contre c'est en ressortant de cette methode que le plantage a lieu.
 
en me relisant la, je ne suis pas sur de la clarté de ce que je dis.
 
v.

Message cité 1 fois
Message édité par vonm le 06-01-2012 à 12:21:24
Reply

Marsh Posté le 06-01-2012 à 14:18:54    


 
mouais.
je ne suis pas convaincu mais comme je ne maitrise pas, je te crois sur parole.
 
Merci beaucoup pour ton aide en tout cas.
 
v.

Reply

Sujets relatifs:

Leave a Replay

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