Fonction PInvoke pour C qui renvoie char *

J’essaie d’écrire du code C # qui appelle une méthode à partir d’une DLL non gérée. Le prototype de la fonction dans la DLL est le suivant:

extern "C" __declspec(dllexport) char *foo(void); 

En C #, j’ai d’abord utilisé:

 [DllImport(_dllLocation)] public static extern ssortingng foo(); 

Il semble fonctionner à la surface, mais je reçois des erreurs de corruption de mémoire lors de l’exécution. Je pense que je pointe vers la mémoire qui se trouve être correcte, mais a déjà été libérée.

J’ai essayé d’utiliser un utilitaire de génération de code PInvoke appelé “P / Invoke Interop Assistant”. Il m’a donné le résultat:

 [System.Runtime.InteropServices.DLLImportAtsortingbute(_dllLocation, EntryPoint = "foo")] public static extern System.IntPtr foo(); 

Est-ce correct? Si oui, comment convertir cet IntPtr en une chaîne en C #?

Vous devez retourner ceci comme IntPtr. Renvoyer un type System.Ssortingng à partir d’une fonction PInvoke requirejs beaucoup de soin. Le CLR doit transférer la mémoire de la représentation native dans celle qui est gérée. C’est une opération facile et prévisible.

Le problème vient cependant avec quoi faire avec la mémoire native qui a été renvoyée par foo (). Le CLR suppose les deux éléments suivants à propos d’une fonction PInvoke qui renvoie directement le type de chaîne

  1. La mémoire native doit être libérée
  2. La mémoire native a été allouée avec CoTaskMemAlloc

Par conséquent, il rassemblera la chaîne, puis appellera CoTaskMemFree sur le blob de mémoire natif. À moins que vous n’allouiez réellement cette mémoire avec CoTaskMemAlloc, cela provoquerait au mieux un plantage de votre application.

Pour obtenir la sémantique correcte, vous devez retourner directement un IntPtr. Utilisez ensuite Marshal.PtrToSsortingng * pour accéder à une valeur Ssortingng gérée. Vous devrez peut-être encore libérer la mémoire native, mais cela dépendra de l’implémentation de foo.

Vous pouvez utiliser la méthode Marshal.PtrToSsortingngAuto.

 IntPtr ptr = foo(); ssortingng str = Marshal.PtrToSsortingngAuto(ptr);