-1

I have a C++ function which performs a number of tasks "PerformJob()". I have a C# wrapper which calls PerformJob(). The job takes a while and I would like the C++ method to send "status updates" back up to the calling C# class. The C++ code is not exposed to the C# class. Adding the C# project as a reference would cause a circular dependency.

I've attempted to pass a delegate through as a parameter but I'm not familiar enough with C++ syntax to make this work (or if it is even possible?). Is there an appropriate way to pass a delegate into C++ as a parameter? Is there a better method to facilitate this communication? I'd like to avoid a dllimport, as I only need to receive updates from this one class.

CSharpClass.cs:

public delegate void CallbackDelegate(ref string status);
public CallbackDelegate jobStatusDelegate;

public void UpdateJobStatus(ref string status)
{
   Job.JobStatus = status;
}

public void StartJob()
{
   jobStatusDelegate = new CallbackDelegate(UpdateJobStatus);
   CPlusClass jobHelper = new CPlusClass();
   jobHelper.PerformJob(jobStatusDelegate);
}

CPlusClass.h:

public ref class CPlusClass
{
   public:
   void PerformJob(delegate del);   // is there c++ delegate type?
};

CPlusClass.cpp:

void CPlusClass::PerformJob(delegate del)
{
   // ....
}
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
rw_
  • 81
  • 11
  • Possible duplicate of [Passing a C# callback function into managed and unmanaged C++ libraries](https://stackoverflow.com/questions/33393690/passing-a-c-sharp-callback-function-into-managed-and-unmanaged-c-libraries) – Kangjun Heo Feb 12 '18 at 15:46
  • C++ has no delegate type, but has Functor of and function pointer. – Kangjun Heo Feb 12 '18 at 15:47
  • @P.Knowledge: That question seems to be all about the p/invoke, which is totally unnecessary here. – Ben Voigt Feb 12 '18 at 15:48
  • @P.Knowledge: Further, he's writing C++/CLI (see. `ref class` in the question's code) not standard C++. – Ben Voigt Feb 12 '18 at 15:48
  • @BenVoigt Oh, I missed `ref`, my bad. sorry. – Kangjun Heo Feb 12 '18 at 15:50
  • 1
    @P.Knowledge: The other clue would have been the way he just `new`s up an instance of the C++/CLI class inside C#. Wouldn't be possible with ordinary C++ classes, only with C++/CLI. – Ben Voigt Feb 12 '18 at 15:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/164977/discussion-between-p-knowledge-and-ben-voigt). – Kangjun Heo Feb 12 '18 at 15:52
  • In .NET Framework, There're features to pass delegates. This can be help: https://msdn.microsoft.com/en-us/library/018hxwa8(v=vs.110).aspx, https://msdn.microsoft.com/en-us/library/bb534960(v=vs.110).aspx – Kangjun Heo Feb 12 '18 at 15:59

1 Answers1

1

C++ doesn't have delegates, but C++/CLI does, and based on ref class your code already is C++/CLI.

Delegates work much like any other reference type, they get stored as a tracking handle with the ^.

In order to not create a dependency on the C#, which would be in the wrong direction, I suggest you use a System::Action<System::String^>^ instead of defining your own delegate type.

public ref class CPlusClass
{
   public:
   void PerformJob(System::Action<System::String^>^ del)
   {
       del->Invoke(gcnew String("Hello World"));
   }
};
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720