Interopération entre C # et une bibliothèque C non gérée

J’ai une petite bibliothèque C dans une DLL et j’ai besoin d’appeler une poignée de ses méthodes.

Il utilise des pointeurs et quelques structures mais est par ailleurs assez simple. Le problème, c’est que je ne suis pas très au courant de l’interopérabilité de .NET avec le monde non géré et que mes tentatives jusqu’à présent continuent de bash les exceptions de violation d’access à la mémoire (probablement parce que j’ai mal compris les indicateurs).

Quelqu’un pourrait-il me donner des indications (ouah un jeu de mots!) Sur la meilleure façon de procéder?

Je vous remercie

extern vconfig_t *Pobsopen(Ppoly_t ** obstacles, int n_obstacles); extern int Pobspath(vconfig_t * config, Ppoint_t p0, int poly0, Ppoint_t p1, int poly1, Ppolyline_t * output_route); extern void Pobsclose(vconfig_t * config); struct vconfig_t { int Npoly; int N; Ppoint_t *P; int *start; int *next; int *prev; }; typedef struct Ppoly_t { Ppoint_t *ps; int pn; } Ppoly_t; typedef Ppoly_t Ppolyline_t; typedef struct Pxy_t { double x, y; } Pxy_t; typedef struct Pxy_t Ppoint_t; typedef struct Pxy_t Pvector_t; 

Vous devriez consulter l’ outil fourni dans cet article de MSDN Magazine qui permet de convertir un extrait de code C en signatures C # P / Invoke et, bien entendu, le message.

L’exécution de l’outil pour votre extrait de code vous donne ceci:

 [System.Runtime.InteropServices.StructLayoutAtsortingbute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct vconfig_t { /// int public int Npoly; /// int public int N; /// Ppoint_t* public System.IntPtr P; /// int* public System.IntPtr start; /// int* public System.IntPtr next; /// int* public System.IntPtr prev; } [System.Runtime.InteropServices.StructLayoutAtsortingbute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct Ppoly_t { /// Ppoint_t* public System.IntPtr ps; /// int public int pn; } [System.Runtime.InteropServices.StructLayoutAtsortingbute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct Pxy_t { /// double public double x; /// double public double y; } public partial class NativeMethods { /// Return Type: vconfig_t* ///obstacles: Ppoly_t** ///n_obstacles: int [System.Runtime.InteropServices.DllImportAtsortingbute("", EntryPoint="Pobsopen")] public static extern System.IntPtr Pobsopen(ref System.IntPtr obstacles, int n_obstacles) ; /// Return Type: int ///config: vconfig_t* ///p0: Ppoint_t->Pxy_t ///poly0: int ///p1: Ppoint_t->Pxy_t ///poly1: int ///output_route: Ppolyline_t* [System.Runtime.InteropServices.DllImportAtsortingbute("", EntryPoint="Pobspath")] public static extern int Pobspath(ref vconfig_t config, Pxy_t p0, int poly0, Pxy_t p1, int poly1, ref Ppoly_t output_route) ; /// Return Type: void ///config: vconfig_t* [System.Runtime.InteropServices.DllImportAtsortingbute("", EntryPoint="Pobsclose")] public static extern void Pobsclose(ref vconfig_t config) ; } 

Vous devriez peut-être écrire votre wrapper en C ++ / CLI, car l’interopérabilité entre le code managé et le code non managé est très transparente.

Mettre à jour

Voici un lien vers un exemple sortingvial: une structure de données C pour imiter la liste de C #>?

J’ai écrit une réponse longue et utile, que StackOverflow a écartée lorsque je l’ai postée.

L’essentiel était:

  1. Vous trouverez peut-être que le site pinvoke.net est utile, même s’il n’est pas toujours précis.
  2. Le source .NET Framework est un référentiel très utile pour les signatures p / invoke correctes pour les fonctions Win32 et m’a souvent inspiré pour mes propres problèmes p / invoke.
  3. La classe Marshal contient beaucoup de fonctions utiles, dont certaines peuvent aider à expliquer des choses comme ce que vous faites réellement avec un IntPtr.

Vous devrez peut-être aussi vous méfier des corrections / épingles – en particulier avec quelque chose comme la structure de votre liste chaînée, en pensant que je ne sais pas comment elle sera utilisée dans votre application gérée.