Summary - P/Invoke and interop
Combine DllImport, Marshal and StructLayout to write a native wrapper.
Summary - P/Invoke and interop
In this group you learned DllImport, Marshal, StructLayout, string marshalling and delegate*. These are the ways to call native code (C libraries, Win32 API) from C#.
Choosing the right marshal type and managing memory by hand is critical for interop safety. Let's now write a small native wrapper.
Exercise Point struct and Marshal.SizeOf
Add the [StructLayout(LayoutKind.Sequential)] struct Point { public int X; public int Y; } struct. In Main write Point p; p.X = 10; p.Y = 20;, get the size with int size = Marshal.SizeOf<Point>(); and print it with Console.WriteLine(size);.
Show example solution
Point p; p.X = 10; p.Y = 20; int size = Marshal.SizeOf<Point>(); Console.WriteLine(size);
Example solution:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct Point
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
Point p;
p.X = 10;
p.Y = 20;
int size = Marshal.SizeOf<Point>();
Console.WriteLine(size);
}
}
Memory and lifecycle
In interop code the key rule: always release memory you allocated with Marshal (FreeHGlobal). Strings that DllImport marshals automatically do not need this, but manual Marshal calls can leak.
Guaranteeing release with a using statement or try/finally is the best practice. This ensures the resource is reclaimed even on error paths.
Exercise Call abs via DllImport
Add the declaration [DllImport("libc.so.6")] static extern int abs(int n);. In Main compute the absolute value with int r = abs(-7); and print it with Console.WriteLine(r);.
Show example solution
int r = abs(-7); Console.WriteLine(r);
Example solution:
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("libc.so.6")]
static extern int abs(int n);
static void Main()
{
int r = abs(-7);
Console.WriteLine(r);
}
}
Test yourself
-
Which copies a managed string to native memory?
- Marshal.StringToHGlobalAnsi
- GC.Collect
- Thread.Sleep
- Console.WriteLine
Show answer
Marshal.StringToHGlobalAnsi — Correct. Marshal.StringToHGlobalAnsi puts a string in native memory.
-
Match the concepts
- DllImport
- Native method call
- Marshal
- Manual conversion
- StructLayout
- Memory layout
- delegate*
- Function pointer