zoukankan      html  css  js  c++  java
  • C++/CLI入门系列 第三篇:C#通过C++/CLI,实现C++的回调函数

    C++/CLI入门系列 第三篇:C#通过C++/CLI,实现C++的回调函数

    萝呆子 2020-06-02 18:02:34 373 收藏 3
    分类专栏: C++/CLI
    版权
    前言:照例啰嗦一下,心急的可略过。做程序员也好些年了,从 iOS 强转 C++ 也有四年了。给后来者一个忠告:如果想要延长自身技术寿命,一定要珍惜时间,好好利用,拼命提升自己技术。
    不说了,怎么过都是一生,即便未来失业了,也不代表活不下去。这个时代,不要给自己添加承受不了的重担,选择自己喜欢的,轻装度过这一生。
    O了,开始搞起!
    已经2020年了,公司要求用VS2019,所以就用这个版本做演示,大差不差~
    第一步:打开VS2019,依次创建三个空的 C# 工程、CLR 工程和 C++ 工程。步骤如下图所示:

     

     

     

     

    第二步:撸代码,如下所示:

    //Cpp.h

    #pragma once

    using CppCallBack = void (__stdcall*)();

    class __declspec(dllexport) MyArith

    {

    public:

    MyArith();

    ~MyArith();

    int GetCppData(unsigned char ch[], int len);

    int RegistCall(CppCallBack pFun);

    void execute();

    private:

    CppCallBack cppCall;

    };

    //Cpp.cpp

    #include "Cpp.h"

    MyArith::MyArith(){}

    MyArith::~MyArith(){}

    int MyArith::GetCppData(unsigned char ch[], int len)

    {

    unsigned char* p = ch;

    for (int i = 0; i < len; i++)

    {

    *(p++) = i % 26 + 65;

    }

    return 0;

    }

    int MyArith::RegistCall(CppCallBack pFun)

    {

    if (pFun != nullptr)

    {

    cppCall = pFun;

    return 0;

    }

    else

    {

    return -1;

    }

    }

    void MyArith::execute()

    {

    cppCall();

    }

    //Cli.h

    #pragma once

    using namespace System;

    using namespace System::Runtime::InteropServices;

    using namespace System::Collections::Generic;

    using namespace System::Collections;

    using namespace std;

    #pragma managed

    namespace CliDll {

    public delegate void CliCallBack();

    public ref class Arith

    {

    public:

    Arith();

    ~Arith();

    int GetCliData(array<unsigned char>^ ch, int len);

    int RegistCall(CliCallBack^ pFun);

    void execute();

    };

    }

    //Cli.cpp

    #include "Cli.h"

    #include "Cpp/Cpp.h"

    MyArith *myArith;

    CliDll::Arith::Arith()

    {

    myArith = new MyArith();

    }

    CliDll::Arith::~Arith()

    {

    myArith->~MyArith();

    }

    int CliDll::Arith::GetCliData(array<unsigned char>^ ch, int len)

    {

    unsigned char* src = new unsigned char[len];

    if (src == nullptr)

    {

    return -1;

    }

    int mark = myArith->GetCppData(src, len);

    if (mark)

    {

    return -2;

    }

    unsigned char* clisrc = src;

    pin_ptr<unsigned char> cssrc = &ch[0];

    for (int i = 0; i < len; i++)

    {

    *(cssrc++) = *(clisrc++);

    }

    delete[] src;

    return 0;

    }

    int CliDll::Arith::RegistCall(CliCallBack^ pFun)

    {

    CppCallBack cliCall = (CppCallBack)Marshal::GetFunctionPointerForDelegate(pFun).ToPointer();

    myArith->RegistCall(cliCall);

    return 0;

    }

    void CliDll::Arith::execute()

    {

    myArith->execute();

    }

    //MyCS.cs

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Threading.Tasks;

    using CliDll;

    namespace CSharp

    {

    public partial class MyCS

    {

    static Arith arith = new Arith();

    public static void MyCallBack()

    {

    byte[] data = new byte[26];

    int mark = MyCS.arith.GetCliData(data, 26);

    for(int i = 0; i < 26; i++)

    {

    Console.WriteLine(data[i]);

    }

    }

    static void Main(string[] args)

    {

    CliCallBack cliCall = new CliCallBack(MyCallBack);

    MyCS.arith.RegistCall(cliCall);

    MyCS.arith.execute();

    Console.ReadLine();

    }

    }

    }


    第三步:配置,参考此系列 第二篇:封装C++ dll库,提供接口给C#调用
    如果和我一样懒,去 Git 仓库 上 clone 吧,建议最好还是敲一遍。我不会告诉你在仓库代码上添加了注释的(手动狗头)。。。
    演示结果如下:

  • 相关阅读:
    Redis使用手册
    log4j.properties 输出指定类日志
    Maven中Jar包冲突,不让某个Jar包打入到工程中
    Cannot refer to the non-final local variable user defined in an enclosing scope
    PANIC: Missing emulator engine program for ‘x86’ CPU.
    Android studio 不能创建Activity等文件
    jenkins打maven包,出现Module Builds里面部分模块没有启动问题
    CentOS7 SFTP服务安装和使用
    记一次阿里云服务器被挖矿程序植入处理(简单记录下)
    利用阿里云高可用虚拟ip+keepalived+mha实现两台mysql的高可用
  • 原文地址:https://www.cnblogs.com/lvdongjie/p/13962904.html
Copyright © 2011-2022 走看看