C++调用C#注册的回调函数
2017-12-28 19:12
501 查看
本文主要讲解C#注册回调函数提供给C++调用,用于异步通知机制。这在编程过程中是经常需要用到的模式。
此过程需要创建三个工程:
1. C++动态库工程
2. C++ CLR 托管动态库工程
3. C# 测试工程
接着前文C++封装成托管模式供C#调用过程创建的C++ CLR托管工程,在此基础上再创建一个C++动态库工程,此工程创建过程比较简单在此不再详细说明,只注意一点如图。
一、C++动态库工程
工程结构图:
二、 C++ CLR 托管动态库工程
此工程的创建在前面文章已经详细说明,此处不在叙述。
工程结构图:
三、C# 测试工程
创建一个C#的控制台应用程序用于测试,此工程中需要引用CppCLR.dll托管动态库,还需要添加using CppCLRNameSpace;才能够使用ClassCLR托管类。
注意:还需要把C++生成的CPPClass.dll添加到C#的bin执行目录下,因为此库需要被CppCLR.dll托管库引用
工程结构图:
测试结果如下:
总结:
对于一些比较复杂类型的数据结构则需要考虑到C#与C++数据类型之间的差异,例如string等,因为C#与C++的string不能够相对应,不能直接传递,需要变换成char*。关于更多数据类型转换可以参考另外一篇博文。C++托管与C#中的数据类型转换
此过程需要创建三个工程:
1. C++动态库工程
2. C++ CLR 托管动态库工程
3. C# 测试工程
接着前文C++封装成托管模式供C#调用过程创建的C++ CLR托管工程,在此基础上再创建一个C++动态库工程,此工程创建过程比较简单在此不再详细说明,只注意一点如图。
一、C++动态库工程
工程结构图:
//CPPClass.h #ifdef CPPCLASS_EXPORTS #define CPPCLASS_API __declspec(dllexport) #else #define CPPCLASS_API __declspec(dllimport) #endif typedef void (_stdcall *CB_FUNCTION_CALLBACK)(int IntputDataClr); // 此类是从 CPPClass.dll 导出的 class CPPCLASS_API CCPPClass { public: CCPPClass(void); bool RegisterFunctionCallback(CB_FUNCTION_CALLBACK cbFunctionCallback); bool InvokeCallbackFunction(); private: CB_FUNCTION_CALLBACK mCallback; };
//CPPClass.cpp #include "stdafx.h" #include "CPPClass.h" CCPPClass::CCPPClass() :mCallback(nullptr) { return; } bool CCPPClass::RegisterFunctionCallback(CB_FUNCTION_CALLBACK cbFunctionCallback) { if(nullptr != cbFunctionCallback){ mCallback = cbFunctionCallback; return true; }else{ mCallback = nullptr; return false; } } bool CCPPClass::InvokeCallbackFunction() { if(nullptr != mCallback){ mCallback(1024); //调用回调函数,把1024传给C# return true; }else{ return false; } }
二、 C++ CLR 托管动态库工程
此工程的创建在前面文章已经详细说明,此处不在叙述。
工程结构图:
//CppCLR.h #include "CPPClass.h" #include <msclr\marshal_cppstd.h> #include <msclr/marshal.h> #include <msclr/marshal_windows.h> #include <msclr/marshal_cppstd.h> #include <msclr/marshal.h> using namespace System; using namespace msclr::interop; using namespace System::Runtime::InteropServices; namespace CppCLRNameSpace { public delegate void FunctionCallback(int IntputDataClr); public ref class ClassCLR { public: ClassCLR(); ~ClassCLR(); bool RegisterFunctionCallback(FunctionCallback^ cbFunctionCallback); bool InvokeCallbackFunction(); private: CCPPClass *mCPPClass; }; }
//CppCLR.cpp #include "stdafx.h" #include "CppCLR.h" using namespace CppCLRNameSpace; ClassCLR::ClassCLR() { mCPPClass = nullptr; mCPPClass = new CCPPClass(); } ClassCLR::~ClassCLR() { delete mCPPClass; mCPPClass = nullptr; } bool ClassCLR::RegisterFunctionCallback(FunctionCallback^ cbFunctionCallback) { IntPtr c_cbDownloadCallback = Marshal::GetFunctionPointerForDelegate(cbFunctionCallback);//可将pvFun强制转化为void*,再强制转化为FUN类型 return mCPPClass->RegisterFunctionCallback(reinterpret_cast<CB_FUNCTION_CALLBACK>(c_cbDownloadCallback.ToInt32())); } bool ClassCLR::InvokeCallbackFunction() { return mCPPClass->InvokeCallbackFunction(); }
三、C# 测试工程
创建一个C#的控制台应用程序用于测试,此工程中需要引用CppCLR.dll托管动态库,还需要添加using CppCLRNameSpace;才能够使用ClassCLR托管类。
注意:还需要把C++生成的CPPClass.dll添加到C#的bin执行目录下,因为此库需要被CppCLR.dll托管库引用
工程结构图:
//Program.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using CppCLRNameSpace; namespace TestCppCLR { class Program { static void Main(string[] args) { ClassCLR mClassCLR = new ClassCLR(); FunctionCallback mFunctionCallback; ClassTemp mClassTemp = new ClassTemp(); mFunctionCallback = new FunctionCallback(mClassTemp.Functions); mClassCLR.RegisterFunctionCallback(mFunctionCallback); mClassCLR.InvokeCallbackFunction(); Thread.Sleep(100000); } } public class ClassTemp { public void Functions(int InputData) { Console.WriteLine(InputData); } } }
测试结果如下:
总结:
对于一些比较复杂类型的数据结构则需要考虑到C#与C++数据类型之间的差异,例如string等,因为C#与C++的string不能够相对应,不能直接传递,需要变换成char*。关于更多数据类型转换可以参考另外一篇博文。C++托管与C#中的数据类型转换
相关文章推荐
- C#调用C++的dll,PInvoke问题和回调函数抛出异常access violation
- C# 调用 C++ 回调函数
- C#调用C++DLL,及回调函数、string参数传递的总结
- c#调用c++带有回调函数方法的实现
- C++ dll 调用C#传入的回调函数,运行一段时间程序自动出错
- C#调用C++DLL中的回调函数(异步的情况,DLL中会在事件触发时调用函数)
- 关于C#中调用C++dll传递回调函数的问题
- c# 调用c++带有回调函数方法的实现
- c#调用c++dll接口及回调函数
- C#调用C++回调函数的问题
- 关于C#中调用C++dll传递回调函数的问题
- c#调用c++回调函数。
- c#调用c++带有回调函数方法的实现
- C#调用C/C++ DLL 参数传递和回调函数的总结
- C#调用c++dll时,关于回调函数
- C# 调用C/C++回调函数
- C# 调用C++回调函数
- Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数
- c#调用c++的回调函数
- C# 如何调用 C++ DLL中的函数接口和回调函数