Possible to call C code from C?
Data Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.
Introduction
Yes, it is absolutely possible to call C++ code from C#. This is a common requirement when you need to reuse an existing C++ library, access low-level system APIs, or offload performance-critical computations to native code while keeping the rest of your application in C#. There are two main approaches: Platform Invocation Services (P/Invoke) for calling C-style functions, and C++/CLI for creating a managed wrapper around C++ classes. This article covers both approaches with working examples and discusses when to choose each one.
Approach 1: P/Invoke
P/Invoke (Platform Invocation Services) lets C# call functions exported from unmanaged DLLs. This works well when the C++ code exposes functions with C-compatible signatures, meaning they use extern "C" to prevent name mangling.
Step 1: Write the C++ DLL
First, create a C++ function and export it from a DLL:
The extern "C" block is critical. Without it, the C++ compiler applies name mangling to function names, and P/Invoke will not be able to find them in the DLL.
Step 2: Call from C#
In your C# project, declare the external functions using the DllImport attribute:
The CallingConvention must match between the C++ and C# sides. Cdecl is the default calling convention for C/C++ functions. If the C++ side uses __stdcall, you must specify CallingConvention.StdCall in C#.
Passing Strings and Arrays
P/Invoke handles data marshaling between managed and unmanaged memory. For strings and arrays, you need to pay attention to how data is converted:
For strings, use [MarshalAs(UnmanagedType.LPStr)] for ANSI strings or [MarshalAs(UnmanagedType.LPWStr)] for wide strings.
Approach 2: C++/CLI Wrapper
When you need to call C++ class methods, use templates, or work with complex data structures, P/Invoke becomes cumbersome. In these cases, C++/CLI provides a better solution. C++/CLI is a language extension that can compile to both managed (.NET) and unmanaged (native) code, making it the ideal bridge between the two worlds.
Step 1: Write the Native C++ Class
Step 2: Create the C++/CLI Wrapper
Step 3: Use the Wrapper in C#
The C# code treats CalculatorWrapper as a normal .NET class. All the complexity of interacting with native C++ is hidden inside the wrapper.
When to Use Each Approach
Use P/Invoke when you are calling standalone C-style functions from an existing DLL. It requires no additional projects or compilers beyond the standard C# toolchain, and it works across platforms with .NET Core and .NET 5+.
Use C++/CLI when you need to interact with C++ classes, use inheritance hierarchies, or work with complex data types. C++/CLI is Windows-only and requires the Visual C++ compiler, but it provides a much cleaner integration for object-oriented C++ code.
Common Pitfalls
Forgetting extern "C". Without this, C++ name mangling makes function names unrecognizable to P/Invoke. You will get a DllNotFoundException or EntryPointNotFoundException at runtime.
Mismatched calling conventions. If the C++ side uses __cdecl but the C# side declares CallingConvention.StdCall, the stack will be corrupted, often causing crashes that are difficult to diagnose.
Memory leaks in C++/CLI wrappers. If you allocate native objects with new in the constructor, you must delete them in both the destructor (~ClassName, called by Dispose) and the finalizer (!ClassName, called by the garbage collector). Otherwise, native memory will leak.
32-bit vs 64-bit mismatches. The DLL and the C# application must target the same architecture. A 64-bit C# process cannot load a 32-bit DLL and vice versa.
Summary
Calling C++ code from C# is well-supported through two primary mechanisms. P/Invoke is the simpler option for C-style functions exported from DLLs and works cross-platform. C++/CLI provides full access to C++ classes and complex types but is limited to Windows. In both cases, pay careful attention to calling conventions, data marshaling, and memory management to avoid crashes and leaks. Choose P/Invoke for simple function calls and C++/CLI when you need object-oriented interop with native C++ code.
Related reading
- PowerShell script to return versions of .NET Framework on a machine?
- Practical difference between List and IEnumerable
- Practical example where Tuple can be used in .Net 4.0?
- Predefined type 'System.Object' is not defined or imported .net 4.6
- Problem with Precision floating point operation in C
- Proper way to initialize a stdarray from a C array
- Prevent Caching in ASP.NET MVC for specific actions using an attribute
- Prevent multiple instances of a given app in .NET?

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseData Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.