Monday, December 27, 2010

Wrapping C/C++ callback in C++/CLI


/**
 * Unmanaged part
 */

typedef boost::function UnmanagedCallback;
typedef bool (__stdcall *CallbackTypeProxy)(int);

class CUnmanaged {
private:
    boost::function m_callback;
public:
    CUnmanaged(const boost::function & callback) : m_callback(callback)
    {
    }

    bool Callback(int n)
    {
        return m_callback(n);
    }
};

/**
 * Managed part
 */

using namespace System::Runtime::InteropServices;

public ref class CManaged 
{
private:
    delegate bool CallbackHandler(int);
    CallbackHandler^ m_callback;
    CUnmanaged * m_object;

    bool Callback(int n)
    {
        printf("%d\n", n);
        return true;
    }
public:
    CManaged()
    {
        m_callback = gcnew CallbackHandler(this, &CManaged::Callback);
        System::IntPtr ip = Marshal::GetFunctionPointerForDelegate(m_callback);
        CallbackTypeProxy cb = static_cast(ip.ToPointer());

        m_object = new CUnmanaged(boost::bind(cb, _1));
    }
    ~CManaged()
    {
         delete m_object;
    }

    bool InvokeCallback(int n)
    {
        return m_object->Callback(n);
    }
};

int main(array ^args)
{
    CManaged c;
    c.InvokeCallback(1);
    c.InvokeCallback(2);
    return 0;
}


No comments:

Post a Comment