Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6097491
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T13:02:58+00:00 2026-05-23T13:02:58+00:00

say I have a C++ library function for computing PI: // pi.h: #ifdef BUILDING_DLL

  • 0

say I have a C++ library function for computing PI:

// pi.h:
#ifdef BUILDING_DLL
#define DLL_MACRO __declspec(dllexport)
#else
#define DLL_MACRO __declspec(dllimport)
#endif

namespace Cpp {
  class PI {
  public:
    static double DLL_MACRO compute();
  };
}; 

// pi.cpp: 
#include "pi.h"
#include <cmath>

double 
Cpp::PI::compute() {
   // Leibnitz summation formulae:
   double sum = 0.0;
   for(long n = 0; n < 100*1000*1000; n++)
     sum += 4.0*pow(-1.0, n)/(2*n + 1.0);
   return sum;
} 

I need to call this function from C#, and I want to use C++/CLI as a “bridge”. However this C++ function is somewhat slow. Therefore the C# code calling this function need to get callbacks telling it how far the function has come in %.
The C# code might need some state, e.g. a progress bar, to deal with this info.
So the callbacks from C++ must enter into a member function on the C# side.

So I introduce:

// piCLI.h: The C++/CLI "bridge" between C# and C++
#include "pi.h"
#pragma once
namespace CLI {
   public ref class PI abstract {
   public:
      double compute() {
        return Cpp::PI::compute();
      }
      virtual void progress(int percentCompleted) = 0;        
   };
 }; 

and

 namespace CSharp
 {
    public class PI : CLI.PI
    {
       public override void progress(int percentCompleted)
       {
          System.Console.WriteLine(percentCompleted + "% completed.");
       }
     }
  }

Now invoking CSharp.PI.compute() works fine :-). It forwards the call to Cpp::PI::compute() as intended.

But how do I get the C++ library to forward progress updates to CSharp.PI.progress() whilst Cpp::PI::compute() is running?

Thanks in advance for any answers!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T13:02:59+00:00Added an answer on May 23, 2026 at 1:02 pm

    I would take a function pointer/delegate approach as well:

    // pi.h:
    #pragma once
    
    #ifndef DLL_MACRO
    #ifdef BUILDING_DLL
    #define DLL_MACRO __declspec(dllexport)
    #else
    #define DLL_MACRO __declspec(dllimport)
    #endif
    #endif
    
    namespace Cpp {
        typedef void (__stdcall *ComputeProgressCallback)(int);
    
        class PI {
        public:
            static double DLL_MACRO compute(ComputeProgressCallback callback);
        };
    }
    
    // pi.cpp: 
    #include "pi.h"
    #include <cmath>
    
    double Cpp::PI::compute(Cpp::ComputeProgressCallback callback) {
        double sum = 0.;
        for (long n = 0L; n != 100000000L; ++n) {
            sum += 4. * std::pow(-1., n) / (2L * n + 1.);
            callback(/*impl*/);
        }
        return sum;
    }
    
    // piCLI.h: The C++/CLI "bridge" between C# and C++
    #pragma once
    #include "pi.h"
    
    namespace CLI {
        public delegate void ComputeProgressDelegate(int percentCompleted);
    
        public ref class PI abstract sealed {
        public:
            static double compute(ComputeProgressDelegate^ callback) {
                using System::IntPtr;
                using System::Runtime::InteropServices::Marshal;
    
                IntPtr cbPtr = Marshal::GetFunctionPointerForDelegate(callback);
                return Cpp::PI::compute(
                    static_cast<Cpp::ComputeProgressCallback>(cbPtr.ToPointer())
                );
            }
        };
    }
    
    namespace CSharp {
        public static class PI {
            public static double compute() {
                CLI.PI.compute(
                    percentCompleted => System.Console.WriteLine(
                        percentCompleted.ToString() + "% completed."
                    )
                );
            }
        }
    }
    

    Or, to override an abstract progress method rather than creating a delegate on the C# side:

    // piCLI.h: The C++/CLI "bridge" between C# and C++
    #pragma once
    #include "pi.h"
    
    namespace CLI {
        public ref class PI abstract {
            delegate void ComputeProgressDelegate(int percentCompleted);
    
        public:
            double compute() {
                using System::IntPtr;
                using System::Runtime::InteropServices::Marshal;
    
                ComputeProgressDelegate^ callback = gcnew ComputeProgressDelegate(
                    this,
                    &PI::progress
                );
                IntPtr cbPtr = Marshal::GetFunctionPointerForDelegate(callback);
                return Cpp::PI::compute(
                    static_cast<Cpp::ComputeProgressCallback>(cbPtr.ToPointer())
                );
            }
    
        protected:
            virtual void progress(int percentCompleted) abstract;
        };
    }
    
    namespace CSharp {
        public sealed class PI : CLI.PI {
            protected override void progress(int percentCompleted) {
                System.Console.WriteLine(
                    percentCompleted.ToString() + "% completed."
                );
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Lets say I have a library function that I cannot change that produces an
Say i have this function that dynamically creates my namespace for me when I
Say, for example, I have many web applications using the same class library compiled
Say I have a library libfoo.so.1 , which depends (according to ldd ) on
Say I want to know if F# has a library function of type ('T
I'm relatively new to DLL importing and function binding. Let's say I have a
I have a .Net library. say with 2 public functions. say one is Summmator
Lets say I have a function f :: State [Int] Int and a function:
Let's say I have the following function. let rec fib n = match n
Let's say there is a library function called get_pack() which returns a Pack object:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.