【问题标题】:Call native std::function from C++/CLI从 C++/CLI 调用本机 std::function
【发布时间】:2020-10-27 16:38:23
【问题描述】:

我有一个本地类,它接收一个 std::function 作为参数,并在某个时间点调用此回调:

class NativeClass
{
public:
    NativeClass(std::function<void(int, const char*)> callback) : m_callback{callback}
    {
    }

    void DoAction()
    {
        ...
        m_callback(3, "asd");
        ...
    }

private:
    std::function<void(int, const char*)> m_callback;
}

假设它位于我无法控制的库中,因此 std::function 是给定的。

现在我有一个 C++/CLI 类,我希望在其中调用这个回调:

public ref class ManagedConsumer()
{
public:
    ManagedConsumer()
    {
        m_nativeClass = new NativeClass(std::bind(&ManagedConsumer::OnCallback, this); // errors: 3374, 2672
        m_nativeClass = new NativeClass([this](...){this->OnCallback(...);}); // errors: 3374, 2672
    }
    void OnCallback(int i, const char* str)
    {
        localInt += i; // must access local variable from this
        // consume callback
    }
private:
    NativeClass *m_nativeClass;
    int localInt;
}

甚至可以捕获 this 变量吗?我不能真正改变 NativeClass 来传递接口或其他东西。

【问题讨论】:

    标签: c++-cli managed-c++


    【解决方案1】:

    您需要在这里使用一些编组,还需要将回调作为委托。

    托管类.h的内容

    #pragma once
    using namespace System::Runtime::InteropServices;
    
    public delegate void CallbackDelegate(int data);
    
    public ref class ManagedClass
    {
        UnmanagedClass* unmanagedClassPtr;
        [MarshalAsAttribute(UnmanagedType::FunctionPtr)]
        CallbackDelegate^ _Delegate;
    public:
        ManagedClass()
        {
            unmanagedClassPtr = new UnmanagedClass(); 
            _Delegate = gcnew CallbackDelegate(this, &ManagedClass::MyCallback);
            auto ptr = Marshal::GetFunctionPointerForDelegate(_Delegate).ToPointer();
            unmanagedClassPtr->setCallback(ptr);
        }
        virtual ~ManagedClass()
        {
            delete unmanagedClassPtr;
        }
        void MyCallback(int s) {
            System::Console::WriteLine("hello from unmanaged");
        };
    };
    

    非托管类.h的内容

    #pragma once
    #include "callbackType.h"
    
    class UnmanagedClass
    {
    public:
        void setCallback(void* _callback)
        {
           callback = (callbackType)_callback;
           callback(13);//call it immediately
        };
    };
    

    我从下一个来源得到这个工作: https://www.codeproject.com/Articles/9903/Calling-Managed-Code-from-Unmanaged-Code-and-viceC++/CLI delegate as function pointer (System.AccessViolationException)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2016-04-27
      • 2012-03-29
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多