Click here to Skip to main content
11,432,427 members (69,227 online)
Click here to Skip to main content

Tagged as

How to make a callback to C# from C/C++ code

, 26 Jun 2013 CPOL
Rate this:
Please Sign up or sign in to vote.
This post shows how to make a callback to C# from C/C++
Almost everyone knows how to make a call to a function in an unmanaged DLL. However, sometimes we wish that we could call C# code from C/C++ code.
Imagine a scenario wherein we have a C# application which has a native C DLL called Engine.dll. There is a function entry named “DoWork” in this DLL that we need to call. Calling DoWork in the engine is as easy as making the following declaration in the C# code:
public static extern void DoWork(); 
…and then using it like any other static C# method in our C# application.
This will work just fine. However, let’s assume DoWork is a long-running task and we want to show a progress or so in the C# app in order to keep our user(s) updated. To make this happen, we need to…
  1. Define an unmanaged delegate in the C# code like –
    delegate void ProgressCallback(int value);
  2. Define callback signature in the C code –
    typedef void (__stdcall * ProgressCallback)(int);
  3. Change DoWork signature in C code to accept ProgressCallback address:
    DLL void DoWork(ProgressCallback progressCallback)
    Note: DLL is…
    #define DLL __declspec(dllexport)
  4. Inside the C# code, we need to create a delegate of type of the unmanaged delegate –
    ProgressCallback callback =
        (value) =>
            Console.WriteLine("Progress = {0}", value);
  5. Then for calling DoWork, we need to do it like this –
Here is a sample source code for a simple application. This code snippet includes a second scenario wherein we have a function in C code called ProcessFile that needs to get back to the C# in order to obtain a file path for further processing - in this case, printing its contents to the console.
#include "Windows.h"

#ifdef __cplusplus
extern "C"
    #define DLL __declspec(dllexport)
    typedef void (__stdcall * ProgressCallback)(int);
    typedef char* (__stdcall * GetFilePathCallback)(char* filter);
    DLL void DoWork(ProgressCallback progressCallback);
    DLL void ProcessFile(GetFilePathCallback getPath);
#ifdef __cplusplus
#include "Main.h"
#include <stdio.h>

DLL void DoWork(ProgressCallback progressCallback)
    int counter = 0;
    for(; counter<=100; counter++)
        // do the work...

        if (progressCallback)
            // send progress update
DLL void ProcessFile(GetFilePathCallback getPath)
    if (getPath)
        // get file path...
        char* path = getPath("Text Files|*.txt");
        // open the file for reading
        FILE *file = fopen(path, "r");
        // read buffer
        char line[1024];
        // print file info to the screen
        printf("File path: %s\n", path ? path : "N/A");
        printf("File content:\n");
        while(fgets(line, 1024, file) != NULL)
            printf("%s", line);
        // close the file
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
class Program
    delegate void ProgressCallback(int value);
    delegate string GetFilePathCallback(string filter);
    public static extern void DoWork([MarshalAs(UnmanagedType.FunctionPtr)] ProgressCallback callbackPointer);
    public static extern void ProcessFile([MarshalAs(UnmanagedType.FunctionPtr)] GetFilePathCallback callbackPointer);
    static void Main(string[] args)
        // define a progress callback delegate
        ProgressCallback callback =
            (value) =>
                Console.WriteLine("Progress = {0}", value);
        Console.WriteLine("Press any key to run DoWork....");
        // call DoWork in C code
        Console.WriteLine("Press any key to run ProcessFile....");
        // define a get file path callback delegate
        GetFilePathCallback getPath =
            (filter) =>
                string path = default(string);
                OpenFileDialog ofd =
                    new OpenFileDialog()
                    Filter = filter
                if (ofd.ShowDialog() == DialogResult.OK)
                    path = ofd.FileName;
                return path;
        // call ProcessFile in C code
Enjoy it Smile


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

United States United States
I got my BS in Software Engineering from Iran, worked there for 4.5 years mainly in industrial automation field. Then I moved to Australia. In Australia, I had a great chance to work at some big companies. Since 2009 I have been living in the States. I received my MS in Information Systems from Illinois State University. Currently, I am a Senior Software Development Engineer.

Comments and Discussions

QuestionInconsistent accessibility Pin
Member 1144213210-Feb-15 6:48
memberMember 1144213210-Feb-15 6:48 
AnswerRe: Inconsistent accessibility Pin
Tecfield6-Mar-15 3:48
memberTecfield6-Mar-15 3:48 
QuestionWorks Great! Pin
Tamok16-Dec-14 8:17
memberTamok16-Dec-14 8:17 
GeneralThanks. Very informative and clear Pin
IssaharNoam11-Oct-14 9:28
memberIssaharNoam11-Oct-14 9:28 
QuestionExcellent and informative Pin
Member 1039745231-Dec-13 15:27
memberMember 1039745231-Dec-13 15:27 
GeneralMy vote of 5 Pin
Rene Pilon24-Jun-13 3:49
memberRene Pilon24-Jun-13 3:49 
Generalnice Pin
cuolyut21-Jun-13 20:10
membercuolyut21-Jun-13 20:10 
Questiondeclare parameter as ProgressCallback instead of long? Pin
Member 64339520-Jun-13 5:24
memberMember 64339520-Jun-13 5:24 
AnswerRe: declare parameter as ProgressCallback instead of long? Pin
Tecfield21-Jun-13 4:42
memberTecfield21-Jun-13 4:42 
QuestionThreaded callbacks [modified] Pin
DaedalusAlpha4-Feb-13 3:34
memberDaedalusAlpha4-Feb-13 3:34 
AnswerRe: Threaded callbacks Pin
Tecfield18-Jul-13 20:10
memberTecfield18-Jul-13 20:10 
GeneralMy vote of 5 Pin
TheMahakhef16-Jan-13 2:58
memberTheMahakhef16-Jan-13 2:58 
GeneralMy vote of 5 Pin
mYashodhar19-Jul-12 19:01
membermYashodhar19-Jul-12 19:01 
QuestionMoving pointer from C/C++ dll to C# callback Pin
kobbi_k4-Jul-12 3:33
memberkobbi_k4-Jul-12 3:33 
GeneralRe: Moving pointer from C/C++ dll to C# callback Pin
Tecfield6-Jul-12 7:04
memberTecfield6-Jul-12 7:04 
GeneralRe: Moving pointer from C/C++ dll to C# callback Pin
Member 64339515-May-13 1:27
memberMember 64339515-May-13 1:27 
GeneralRe: Moving pointer from C/C++ dll to C# callback Pin
Tecfield15-May-13 3:26
memberTecfield15-May-13 3:26 
AnswerRe: Moving pointer from C/C++ dll to C# callback Pin
Tecfield6-Jul-12 7:10
memberTecfield6-Jul-12 7:10 
GeneralMy vote of 5 Pin
Shmuel Zang20-Jun-12 11:12
memberShmuel Zang20-Jun-12 11:12 
GeneralMy vote of 5 Pin
juan_tabares00130-May-12 21:23
memberjuan_tabares00130-May-12 21:23 
QuestionCongratulations, so easy and simple Pin
Miguel Correia Lima7-May-12 8:34
memberMiguel Correia Lima7-May-12 8:34 
GeneralReason for my vote of 5 nice article Pin
san123pune26-Feb-12 9:39
membersan123pune26-Feb-12 9:39 
GeneralNice... Pin
jaffar Ramnad13-Feb-12 22:00
memberjaffar Ramnad13-Feb-12 22:00 
GeneralReason for my vote of 5 good explanation, straight forward! ... Pin
Emiel Duivenvoorden31-Jan-12 6:30
memberEmiel Duivenvoorden31-Jan-12 6:30 
GeneralReason for my vote of 5 ...Once upon a time I needed such fu... Pin
kosmoh24-Jan-12 21:12
memberkosmoh24-Jan-12 21:12 
General[UnmanagedFunctionPointer(CallingConvention.StdCall)] de... Pin
Selvin23-Jan-12 23:49
memberSelvin23-Jan-12 23:49 
GeneralRe: Thanks for the update :) I modified it to reflect your sugge... Pin
Tecfield24-Jan-12 4:04
memberTecfield24-Jan-12 4:04 
QuestionNice ! Pin
raananv31-Jan-12 12:27
memberraananv31-Jan-12 12:27 
AnswerRe: Nice ! Pin
Tecfield31-Jan-12 17:19
memberTecfield31-Jan-12 17:19 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150428.2 | Last Updated 26 Jun 2013
Article Copyright 2012 by Tecfield
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid