1

I have a c++ function which is expecting a function object (AuthenticateNotifyFunc) to be passed to it thus:

class lc_Authenticate
{
public:
   typedef enum {
     kAbort,
     kContinue
   } lc_AuthenticateStatus;

   typedef std::tr1::function<lc_AuthenticateStatus (const string &msg)> AuthenticateNotifyFunc;

   bool Authenticate(lc_AuthenticateParams &params,
                     AuthenticateNotifyFunc notifyFunc);
}

Within a managed c++ project, I am attempting to define a parameter to pass to the above function thus:

public ref class Form1 : public System::Windows::Forms::Form
{
    public:
    lc_Authenticate::lc_AuthenticateStatus UpdateStatus(const string &msg)
    {
        <<DO SOMETHING>>
        return(lc_Authenticate::kContinue);
    }
    void test()
    {
        string appKey, appSecret;
        appKey = GetString(this->appKeyTextBox->Text);
        appSecret = GetString(this->appSecretTextBox->Text);

        lc_Authenticate dbauth;
        lc_AuthenticateParams params(appKey, appSecret);

        //  DOESN'T COMPILE won't let me take address of member function
        // or know about _1
        lc_Authenticate::AuthenticateNotifyFunc func =
            std::tr1::bind(&Form1::UpdateStatus, this, _1);

        dbauth.Authenticate(params, func);
    }
};

So I am trying to implement a generic method of passing a function to a c++ method in such a way that it doesn't care whether the passed function is static or a member function. And I'm not clear how do do this from managed code.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • This can be accomplished with [`Marshal::GetFunctionPointerForDelegate`](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.getfunctionpointerfordelegate.aspx), but it's going to be horrendously ugly. _Why_ do you want to do this? Having a clear separation between your C++ code and your C++/CLI code is a good thing; coupling them this tightly is just going to be painful. – ildjarn May 25 '12 at 18:59
  • related: http://stackoverflow.com/questions/163757/how-to-use-boostbind-in-c-cli-to-bind-a-member-of-a-managed-class – Nate Kohl May 25 '12 at 19:01

1 Answers1

3

You cannot bind to an instance method of a managed class by design. The garbage collector moves the object around when compacting the heap, causing this to change. You'll need to use a managed delegate. So you can't avoid a native helper class that provides the stable callback you need for your function<>. You can get back to managed code from there with Marshal::GetFunctionPointerForDelegate().

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536