首页 > 解决方案 > 从包装原生 C++ 类的 CLI 类调用 C# 委托

问题描述

我有一个 C++ 类的 CLI 包装器。C++ 类有一个回调,它传递一个 char* 数组和该数组的长度。

void (CPP_CALLBACK*)(char* data, unsigned int dataLength)

在 C# 领域,我有这个回调

  private delegate void AppPacketReceivedDelegate(byte[] data);

我的 CLI 包装器收到 CPP_CALLBACK 回调,然后必须以某种方式调用 C# 委托。

关于如何做到这一点的任何想法?我试过了

System::Action<cli::array<char>^>

但我不确定如何将委托与此操作相匹配。

更新:

我将委托转换为函数指针,然后我可以使用以下语法从 CLI 调用函数指针:

  typedef void(__stdcall * WRAPPER_APP_PACKET_CALLBACK) (cli::array<unsigned char>^);

但是,当我调用它时,数组的大小始终为 1 !

标签: c#.netnative

解决方案


这是一个简单的示例,与您的情况不完全匹配,但可以快速适应。

CppClass.h

namespace MyCppNamespace
{
    typedef void (__stdcall *callback_function)(int, const char*);

    class CppClass
    {
    private:
        callback_function _callbackFunc;

    public:
        void DoSomething(callback_function callbackFunc);
    }
}

点网类.cs

namespace MyManagedNamespace
{
    public delegate void ManagedCallback(int size, string message);
}

CliWrapperClass.h

#include "CppClass.h"

using namespace MyManagedNamespace;

namespace MyCliNamespace
{
    public ref class CliWrapperClass
    {
    private:
        CppClass *_cppClass;

    public:
        void DoSomething(ManagedCallback ^ callback);
    }
}

CliWrapperClass.cpp

#include "CliWrapperClass.h"

namespace MyCliNamespace
{
    void CliWrapperClass::DoSomething(ManagedCallback ^ callback)
    {        
        System::IntPtr callbackPtr = System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(callback);

        _cppClass->DoSomething(static_cast<callback_function>(callbackPtr.ToPointer())); 
    }
}

在 .Net 类中,您可以通过以下方式创建一个实例CliWrapperClass并调用其DoSomething(...)函数:

namespace MyManagedNamespace
{
    public class ManagedClass
    {
        private ManagedCallback _callback = MyCallback;

        private void MyCallback(int size, string message)
        {
            // Do what you want ...
        }

        public void MyFunction()
        {
            CliWrapperClass wrapper = new CliWrapperClass();
            wrapper.DoSomething(_callback);
        }
    }
}

推荐阅读