Passer des chaînes entre C# et DLL C : un exemple minimal
Énoncé du problème
Malgré suivant une approche apparemment simple, le passage de chaînes entre C# et une DLL C via l'interopérabilité provoque un System.AccessViolationException. Le code dans les deux langues semble correct, ce qui crée une confusion quant à la cause première du problème.
Code C
Le code C définit une fonction, concat, qui concatène deux chaînes et renvoie le résultat. Cette fonction est marquée pour l'exportation vers la DLL à l'aide de __declspec(dllexport).
extern "C" { string concat(string a, string b){ return a + b; } }
Code C#
En C#, le code importe la fonction concat à l'aide de DllImport. La CallingConvention est définie sur Cdecl pour correspondre à la convention C.
[DllImport("*****.dll", CallingConvention = CallingConvention.Cdecl)] static extern string concat(string a, string b);
Exception et analyse
Appel de concat("a", "b") en C# une System.AccessViolationException. Cette exception indique qu'un accès mémoire non valide se produit dans le code natif.
Solution : types compatibles avec l'interopérabilité
Le coupable du problème réside dans l'utilisation de C std ::chaîne à travers la limite d'interopérabilité. C# ne peut pas créer ou gérer directement les objets std::string. Au lieu de cela, des types compatibles avec l'interopérabilité doivent être utilisés pour l'échange de données.
Types de données adaptés à l'interopérabilité
Les types d'interopérabilité appropriés incluent des tableaux de caractères terminés par un caractère nul pour transmettre des chaînes à partir de C# à C. Lors du passage de chaînes de C à C#, un StringBuilder peut être utilisé, l'appelant allouant le tampon et l'appelé y écrivant.
Code modifié
En C, la fonction concat peut être déclarée avec les paramètres char* et int pour recevoir un buffer et sa longueur.
extern "C" { void concat(char *str, int len) { // Concatenate strings and write to buffer } }
En C#, le StringBuilder peut être utilisé.
[DllImport("...", CallingConvention = CallingConvention.Cdecl)] static extern void concat(StringBuilder str, int len); .... StringBuilder sb = new StringBuilder(10); concat(sb, sb.Capacity);
En utilisant des types de chaînes compatibles avec l'interopérabilité, l'échange de chaînes entre C# et la DLL C peut être facilité efficacement.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!