c# - 从包装原生 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 !
解决方案
这是一个简单的示例,与您的情况不完全匹配,但可以快速适应。
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);
}
}
}
推荐阅读
- android - 活动转换期间的动画视图
- docker - 构建多架构 Docker 映像时强制架构
- r - 如何在ggplot2中对齐Boxplot和Violinplot的重叠
- ubuntu - 访问 minikube 仪表板 - (Ubuntu20.04 服务器)VM 运行在带有 VirtualBox 6.1 的 Windows 10 主机上
- databricks - databricks 中的 csv 文件路径(FileNotFoundError: [Errno 2] 没有这样的文件或目录)
- javascript - 如何检查一个html元素是否在其他元素之上?
- python-3.x - 如何从 python 文件运行 bash 脚本?
- hibernate - 如何在 application.yml 文件中设置 org.hibernate.org.hibernate.FlushMode=MANUAL
- python - 在 Visual Studio 2012 上使用 Web 部署发布我的烧瓶项目后,我得到“无法访问此站点”
- java - 如何在 NetBeans 12.4 中添加 Hibernate 插件