web-dev-qa-db-fra.com

Comment passer un const char * à une fonction C à partir de C #?

J'essaie d'appeler une simple fonction C à partir d'une externe DLL à partir de mon application C #. Cette fonction est définie comme

void set_param(const char *data)

Maintenant, j'ai des problèmes avec cette fonction:

  1. Comment spécifier ce "const" dans le code C #? public static extern void set_param(sbyte *data) semble manquer la partie "const".

  2. Comment puis-je remettre une chaîne C simple de 8 bits lors de l'appel de cette fonction? Un appel à set_param("127.0.0.1") entraîne un message d'erreur, "ne peut pas convertir de 'chaîne' en 'sbyte'" *.

22
Elmi

Il semble que vous utiliserez le jeu de caractères ANSI, vous pouvez donc déclarer le P/Invoke comme suit:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi)]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)] string lpString);

Le marshaller .NET gère la création de copies de chaînes et la conversion des données au bon type pour vous.

Si vous rencontrez une erreur avec une pile non équilibrée, vous devrez définir la convention d'appel pour qu'elle corresponde à votre DLL C, par exemple:

[DllImport("yourdll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]

Voir pinvoke.net pour de nombreux exemples d'utilisation des fonctions de l'API Windows.

Voir également documentation de Microsoft sur les chaînes de pinvoking .

34
Matthew Watson

UNE const char* est simplement un string en .NET - le côté managé ne comprend pas (encore) la notion de paramètres en lecture seule.

Si vous l'utilisez dans un contexte P/Invoke, vous devez déclarer un attribut MarshalAs et le marshaler en tant que LPStr. La signature qui en résulterait ressemblerait à quelque chose

[DllImport("SomeModule.dll")]
public static extern void set_param([MarshalAs(UnmanagedType.LPStr)]string lpString);

Il y a aussi ceci article sur MSDN avec plus d'informations sur la façon de marshaler les chaînes natives vers un environnement géré.

5
aevitas