none
how to pass C++(Unmanaged) function pointer to C#(managed) delegate

    Question

  • Dear All:

       I write a wapper for calling managed code in unmanaged code. There is a function use event callback.

       C#: A class has

      public delegate bool GetStatus (string status);

      public static bool Run(string str, GetStatus callbackStatus);

     C++ : typedef bool (__stdcall GetStatus)(char*);

      extern "C" __declspec( dllexport ) bool Run(char* str, GetStatus * callbackStatus)

    {

            String ^ str1 = gcnew String(str);

            return A.Run(str1, ...);   //how convert  GetStatus * to A.GetStatus

    }

    Thanks!

    Karry

     

     

    Friday, August 06, 2010 6:36 AM

Answers

  • Consider a helper managed class like this:

     

    ref class MyClass

    {

                GetStatus * const mGetStatus;

     

    public:

     

                MyClass(GetStatus * gs) : mGetStatus(gs) {}

     

     

                bool CallGetStatus(String ^ status)

                {

                            char * s = ""; // TODO: obtain the string from 'status'

                            return mGetStatus(s);

                }

    };

     

    Then inside Run:

     

    MyClass ^ cl = gcnew MyClass(callbackStatus);

    return A::Run(str1, gcnew A::GetStatus(cl, &MyClass::CallGetStatus));

    • Marked as answer by Karry_Wong Friday, August 06, 2010 8:51 AM
    Friday, August 06, 2010 7:17 AM

All replies

  • Consider a helper managed class like this:

     

    ref class MyClass

    {

                GetStatus * const mGetStatus;

     

    public:

     

                MyClass(GetStatus * gs) : mGetStatus(gs) {}

     

     

                bool CallGetStatus(String ^ status)

                {

                            char * s = ""; // TODO: obtain the string from 'status'

                            return mGetStatus(s);

                }

    };

     

    Then inside Run:

     

    MyClass ^ cl = gcnew MyClass(callbackStatus);

    return A::Run(str1, gcnew A::GetStatus(cl, &MyClass::CallGetStatus));

    • Marked as answer by Karry_Wong Friday, August 06, 2010 8:51 AM
    Friday, August 06, 2010 7:17 AM
  • It is work, thanks!

    Friday, August 06, 2010 8:52 AM
  • While I prefer Viorel_'s approach, it's worth knowing that there is another option:

    typedef bool (__stdcall GetStatus)(char*);
    extern "C" __declspec(dllexport) bool Run(char* str, GetStatus* callbackStatus)
    {
    	using System::Runtime::InteropServices::Marshal;
    
    	String^ str1 = gcnew String(str);
    	A::GetStatus^ del = safe_cast<A::GetStatus^>(Marshal::GetDelegateForFunctionPointer(IntPtr(callbackStatus), A::GetStatus::typeid));
    	return A::Run(str1, del);
    }
    
    Friday, August 06, 2010 11:01 AM