Chargement...

Interop en C# (Utilisation de bibliothèques C/C++)

Apprenez l’Interop en C# pour utiliser des bibliothèques C/C++, y compris P/Invoke et la gestion du code non managé.

Dans les applications .NET, il est parfois nécessaire d’utiliser des bibliothèques C ou C++ existantes. Cette situation est appelée Interop (interopérabilité). Le langage C# permet d’accéder au code non managé grâce à l’attribut DllImport. Ainsi, des fonctions hautes performances ou de bas niveau système peuvent être appelées directement.


Appeler une fonction native avec DllImport

Sous Windows, il est possible d’appeler directement depuis C# des fonctions provenant de bibliothèques système telles que user32.dll ou kernel32.dll. Pour cela, on utilise l’espace de noms System.Runtime.InteropServices.


using System;
using System.Runtime.InteropServices;

class Program
{
    // Import d’une fonction de l’API Win32
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    public static extern int MessageBox(IntPtr hWnd, string text, string caption, int type);

    static void Main()
    {
        MessageBox(IntPtr.Zero, "Bonjour Interop !", "Exemple Interop", 0);
    }
}

Ici, la fonction API Win32 MessageBox est appelée. Bien que compilé en C#, c’est en réalité du code natif (C) qui s’exécute.


Appeler une fonction écrite en C

Vous pouvez également utiliser une bibliothèque C/C++ que vous avez écrite vous-même (par exemple mylib.dll). Tout d’abord, définissez une fonction côté C :


// mylib.c
__declspec(dllexport) int AddNumbers(int a, int b)
{
    return a + b;
}

// Import côté C#
using System.Runtime.InteropServices;

class NativeMethods
{
    [DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int AddNumbers(int x, int y);
}

class Program
{
    static void Main()
    {
        int resultat = NativeMethods.AddNumbers(5, 7);
        Console.WriteLine($"Somme : {resultat}");
    }
}

Dans cet exemple, la fonction AddNumbers écrite en C est appelée depuis C#. Les paramètres sont automatiquement convertis vers le type approprié grâce au marshaling.


Struct et Marshaling

Les bibliothèques C n’utilisent pas seulement des types simples, mais aussi des struct. Dans ce cas, la même structure doit être définie côté C# avec l’attribut StructLayout.


// C côté
typedef struct
{
    int width;
    int height;
} Size;

__declspec(dllexport) int CalcArea(Size s)
{
    return s.width * s.height;
}

// C# côté
[StructLayout(LayoutKind.Sequential)]
public struct Size
{
    public int width;
    public int height;
}

class NativeMethods
{
    [DllImport("mylib.dll")]
    public static extern int CalcArea(Size s);
}

class Program
{
    static void Main()
    {
        var taille = new Size { width = 10, height = 20 };
        int surface = NativeMethods.CalcArea(taille);
        Console.WriteLine($"Surface : {surface}");
    }
}

Performance et Sécurité


TL;DR

  • Interop : Permet d’accéder aux bibliothèques C/C++ depuis C#.
  • Les fonctions natives sont appelées avec l’attribut DllImport.
  • Les structs doivent être correctement mappés avec StructLayout.
  • Il existe un coût en performance ; à utiliser avec précaution.

Articles connexes