Possible to call C code from C?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
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 courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.