Tutorial: Debug C# and C++ in the same debugging session

Applies to: yesVisual Studio noVisual Studio for Mac

Note

This article applies to Visual Studio 2017. If you're looking for the latest Visual Studio documentation, see Visual Studio documentation. We recommend upgrading to the latest version of Visual Studio. Download it here

Visual Studio lets you enable more than one debugger type in a debugging session, which is called mixed-mode debugging. In this tutorial, you learn to debug both managed and native code in a single debugging session.

This tutorial shows how to debug native code from a managed app, but you can also debug managed code from a native app. The debugger also supports other types of mixed-mode debugging, such as debugging Python and native code, and using the script debugger in app types such as ASP.NET.

In this tutorial, you will:

  • Create a simple native DLL
  • Create a simple .NET Core or .NET Framework app to call the DLL
  • Configure mixed-mode debugging
  • Start the debugger
  • Hit a breakpoint in the managed app
  • Step into the native code

Prerequisites

If you don't have Visual Studio, go to the Visual Studio downloads page to install it for free.

If you have Visual Studio installed, but don't have the workloads you need, select Open Visual Studio Installer in the left pane of the Visual Studio New Project dialog box. In the Visual Studio Installer, select the workloads you need, and then select Modify.

Create a simple native DLL

To create the files for the DLL project:

  1. Open Visual Studio and create a project.

    From the top menu bar, choose File > New > Project. In the left pane of the New project dialog box, under Visual C++, choose Other, and then in the middle pane choose Empty Project. Then, type a name like Mixed_Mode_Debugging and click OK.

    If you don't see the Empty Project project template, go to Tools > Get Tools and Features..., which opens the Visual Studio Installer. The Visual Studio Installer launches. Choose the Desktop development with C++ workload, then choose Modify.

    Visual Studio creates the project.

  2. In Solution Explorer, select Source Files, and then select Project > Add New Item. Or, right-click Source Files and select Add > New Item.

  3. In the New Item dialog, select C++ file (.cpp). Type Mixed_Mode.cpp in the Name field, and then select Add.

    Visual Studio adds the new C++ file to Solution Explorer.

  4. Copy the following code into Mixed_Mode.cpp:

    #include "Mixed_Mode.h"
    
  5. In Solution Explorer, select Header Files, and then select Project > Add New Item. Or, right-click Header Files and select Add > New Item.

  6. In the New Item dialog, select Header file (.h). Type Mixed_Mode.h in the Name field, and then select Add.

    Visual Studio adds the new header file to Solution Explorer.

  7. Copy the following code into Mixed_Mode.h:

    #ifndef MIXED_MODE_MULTIPLY_HPP
    #define MIXED_MODE_MULTIPLY_HPP
    
    extern "C"
    {
      __declspec(dllexport) int __stdcall mixed_mode_multiply(int a, int b) {
        return a * b;
      }
    }
    #endif
    
  8. Select File > Save All or press Ctrl+Shift+S to save the files.

To configure and build the DLL project:

  1. In the Visual Studio toolbar, select Debug configuration and x86 or x64 platform. If your calling app will be .NET Core, which always runs in 64-bit mode, select x64 as the platform.

  2. In Solution Explorer, select the Mixed_Mode_Debugging project node and select the Properties icon, or right-click the project node and select Properties.

  3. At the top of the Properties pane, make sure the Configuration is set to Active(Debug) and the Platform is the same as what you set in the toolbar: x64, or Win32 for x86 platform.

    Important

    If you switch platform from x86 to x64 or vice versa, you must reconfigure the properties for the new platform.

  4. Under Configuration Properties in the left pane, select Linker > Advanced, and in the dropdown next to No Entry Point, select No. If you had to change it to No, select Apply.

  5. Under Configuration Properties, select General, and in the dropdown next to Configuration Type, select Dynamic Library (.dll). Select Apply, and then select OK.

    Switch to a native DLL

  6. Select the project in Solution Explorer and then select Build > Build Solution, press F7, or right-click the project and select Build.

    The project should build with no errors.

Create a simple managed app to call the DLL

  1. Open Visual Studio and create a new project.

    From the top menu bar, choose File > New > Project. In the left pane of the New project dialog box, under Visual C#, choose Windows Desktop, and then in the middle pane choose Console App (.NET Framework) or Console App (.NET Core).

    Then, type a name like Mixed_Mode_Calling_App and click OK.

    If you don't see the correct project template, go to Tools > Get Tools and Features..., which opens the Visual Studio Installer. Choose the correct .NET workload as described in the prerequisites, and then choose Modify.

    Note

    You could also add the new managed project to your existing C++ solution. We are creating the project in a new solution to make the mixed-mode debugging task more difficult.

    Visual Studio creates the empty project and displays it in Solution Explorer.

  2. Replace all the code in Program.cs with the following code:

    using System;
    using System.Runtime.InteropServices;
    
    namespace Mixed_Mode_Calling_App
    {
        public class Program
        {
            // Replace the file path shown here with the
            // file path on your computer. For .NET Core, the typical (default) path
            // for a 64-bit DLL might look like this:
            // C:\Users\username\source\repos\Mixed_Mode_Debugging\x64\Debug\Mixed_Mode_Debugging.dll
            // Here, we show a typical path for a DLL targeting the **x86** option.
            [DllImport(@"C:\Users\username\source\repos\Mixed_Mode_Debugging\Debug\Mixed_Mode_Debugging.dll", EntryPoint =
            "mixed_mode_multiply", CallingConvention = CallingConvention.StdCall)]
            public static extern int Multiply(int x, int y);
            public static void Main(string[] args)
            {
                int result = Multiply(7, 7);
                Console.WriteLine("The answer is {0}", result);
                Console.ReadKey();
            }
        }
    }
    
  3. In the new code, replace the file path in [DllImport] with your file path to the Mixed_Mode_Debugging.dll you just created. See the code comment for hints. Make sure to replace the username placeholder.

  4. Select File > Save Program.cs or press Ctrl+S to save the file.

Configure mixed-mode debugging

  1. In Solution Explorer, select the Mixed_Mode_Calling_App project node and select the Properties icon, or right-click the project node and select Properties.

  2. Enable native code debugging in the properties.

  3. If you are targeting an x64 DLL from a .NET Framework app, change the platform target from Any CPU to x64. To do this, you may need to select Configuration Manager from the Debug toolbar's Solution Platform drop-down. Then, if you can't switch to x64 directly, create a New Configuration that targets x64.

Set a breakpoint and start debugging

  1. In the C# project, open Program.cs. Set a breakpoint on the following line of code by clicking in the far left margin, selecting the line and pressing F9, or right-clicking the line and selecting Breakpoint > Insert Breakpoint.

    int result = Multiply(7, 7);
    

    A red circle appears in the left margin where you set the breakpoint.

  2. Press F5, select the green arrow in the Visual Studio toolbar, or select Debug > Start Debugging to start debugging.

    The debugger pauses on the breakpoint that you set. A yellow arrow indicates where the debugger is currently paused.

Step in and out of native code

  1. While debugging is paused in the managed app, press F11, or select Debug > Step Into.

    The Mixed_Mode.h native header file opens, and you see the yellow arrow where the debugger is paused.

  2. Now, you can set and hit breakpoints and inspect variables in the native or managed code.

    • Hover over variables in the source code to see their values.

    • Look at variable and their values in the Autos and Locals windows.

    • While paused in the debugger, you can also use the Watch windows and the Call Stack window.

  3. Press F11 again to advance the debugger one line.

  4. Press Shift+F11 or select Debug > Step Out to continue execution and pause again in the managed app.

  5. Press F5 or select the green arrow to continue debugging the app.

Congratulations! You have completed the tutorial on mixed-mode debugging.

Next step

In this tutorial, you learned how to debug native code from a managed app by enabling mixed-mode debugging. For an overview of other debugger features, see: