将非托管方法作为回调传递给托管 C++/CLI class

Passing unmanaged method as callback to managed C++/CLI class

我想将 C++ 成员函数作为回调传递给 C# 项目。我在 C++/CLI 中有其他项目,我想通过它来完成。

因此,在我的 C++/CLI 项目的非托管 C++ 中,我有一个函数对象:std::function<void(int)>callback;

此函数来自我的 C++ 项目并且运行良好,我将其保存在那里作为示例以避免上一步。现在,我想将此回调函数传递给我的 C# 项目。为此,我在非托管 C++ 中创建了一个方法,将其传递给托管 C++,并最终将其传递给 C#。我想要这样的东西:

// Unmanaged class
public class Wrapper
{
public:
    std::function<void(int)>callback;

    void ReturnToCallback(int data)
    {
        callback(data);
    }

    void PassCallback()
    {
        NETWrapper netWrapper;
        netWrapper.TestCallback(ReturnToCallback);
    }
};

//Managed class
public ref class NETWrapper
{
public:
    void TestCallback(Action<int>^ callback)
    {
       StartGenerator^ startGen = gcnew StartGenerator(callback);
    }
};

// C# 
public class StartGenerator
{
    private Communication comm;

    public StartGenerator(Action<int> callback)
    {
        comm = Communication.Instance;
        comm.callback = callback;
    }
}

当然,这个解决方案在编译时给我返回一个错误:

Error 3 error C3867: 'IfaceXXX::Wrapper::ReturnToCallback': function call missing argument list; use '&IfaceXXX::Wrapper::ReturnToCallback' to create a pointer to member d:\XXX.h

我尝试了其他方法,例如获取函数指针的委托,这样我就可以在托管 C++ 上工作并将其传递给 C#,但我无法正确实现它。您认为最好的尝试方法是什么?

  1. 使 Wrapper::callback 成为指向 std::function 的指针。
  2. 将包装器更改为 ref class

就是这样。

public ref class Wrapper
{
public:
    std::function<void(int)>* callback;

    void ReturnToCallback(int data)
    {
        (*callback)(data);
    }

    void PassCallback()
    {
        NETWrapper netWrapper;
        netWrapper.TestCallback(gcnew Action<int>(this, &Wrapper::ReturnToCallback));
    }
};

现在您确实需要管理 std::function 的生命周期,也许 my clr_scoped_ptr 可以告诉您如何做到这一点。