zoukankan      html  css  js  c++  java
  • VC++ 调用C# dll 回调函数,实现MQTT协议客户端通信

    需求:要实现MQTT客户端通信,最终需要变成 MFC 的dll 供别人调用

    困难:c++的MQTT库的编译遇到很多障碍,而且有一个现成的c# 写的MQTT通信例子,而且已经验证过可以通信

    解决办法:使用 c# 完成MQTT通信,再用c++调用

    准备调试环境,准备MQTT服务器,准备MQTT客户端,MQTT服务端我使用 Apollo服务器,客户端使用MQTTX 客户端工具

    支持这个服务器运行需要 jdk 环境,版本是jdk 8 点多

    https://pan.baidu.com/s/1O4ph-ttUr_KaQzBcERoUVg  提取码:oofx

    jdk 安装后需要配置环境变量

    系统变量中

      Path 中 增加 C:Program Files (x86)Javajdk1.8.0_291in       C:Program Files (x86)Javajre1.8.0_291in

      增加 JAVA_HOME  C:Program Files (x86)Javajdk1.8.0_291

    Apollo服务器下载      参考:https://blog.csdn.net/lilealyh/article/details/79867919

    https://pan.baidu.com/s/1bMg5XzJaEP5e75lFdAGNEw  提取码:qfhd

    创建自己的服务器

    下载之后解压到自己电脑的某个目录(d:server)

    win+R 进入到命令行进入到一下目录

    cd d:serverapolloapache-apollo-1.7.1in

    执行命令:
    apollo.cmd create myBroker

    执行完之后就可以在该目录d:server\apolloapache-apollo-1.7.1in生成一个自己的myBroker文件

    启动服务器

    每次测试都要启动服务器,别服务器没启动就判断客户端一直连不上

    进入到自己创建的myBrokerin目录
    cd d:serverapolloapache-apollo-1.7.1inmyBrokerin
    执行命令: apollo-broker.cmd run

     登陆到服务器后台

    在浏览器中输入: 127.0.0.1:61680  即可登陆到后台服务器
    默认的用户名和密码是:admin,password
     

     MQTT客户端 MQTTX

    https://pan.baidu.com/s/1h2lpTQeWDpMeRtTVvz_VCQ    提取码:det0          使用方法自己摸索

    C# dll 编写

    MQTT dll   这个东西是网上下载的  这个环境是.net framework 4.6.1

    https://pan.baidu.com/s/13cvuQO_KcvObaYzfnoBLog  提取码:  tcyb

    创建一个 c# 类库 项目

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Net;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using uPLibrary.Networking.M2Mqtt;
    using uPLibrary.Networking.M2Mqtt.Messages;
    
    namespace MQTTLibrary
    {
        public class MyMQTTClient
        {
            private MqttClient m_MQTTClient;
    
            //连接
            public bool Connect(string sIP, int iPort, string sID, string sUser, string sPSD)
            {
                try
                {
                    m_MQTTClient = new MqttClient(sIP, iPort, false, null, null, 0);
    
                    m_MQTTClient.MqttMsgPublishReceived += MqttMsgPublishReceived;
                    m_MQTTClient.MqttMsgSubscribed += MqttMsgSubscribedEventHandler;
    
                    m_MQTTClient.Connect(sID, sUser, sPSD);
                }
                catch (Exception ea)
                {
                    MessageBox.Show("连接失败:" + ea.Message);
                    return false;
                }
                return true;
            }
    
            //断开
            public bool Disconnect()
            {
                if (m_MQTTClient != null && m_MQTTClient.IsConnected)
                    m_MQTTClient.Disconnect();
    
                return true;
            }
    
            public string m_strTop;
            public string m_strMsg;
    
            public delegate void CallBack(string strTopic, string strMsg); //声明委托
            public CallBack myCallBack;
            //发布接收
            public void MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
            {
                m_strTop = e.Topic;
                m_strMsg = Encoding.UTF8.GetString(e.Message);
    
                myCallBack(m_strTop, m_strMsg);
                //MessageBox.Show(m_strTop);
                //MessageBox.Show(m_strMsg);
            }
    
    
            //订阅处理
            public void MqttMsgSubscribedEventHandler(object sender, MqttMsgSubscribedEventArgs e)
            {
                string top = e.MessageId.ToString();
                string val = e.MessageId.ToString();
            }
    
    
            //订阅
            public bool Subscribe(string strTopic)
            {
                string[] STopics = {"1234567890#####", strTopic};//这里是个bug,这个数组只有一个元素的时候会崩溃
                byte[] qosLevels = { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE, MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE };
    
                try
                {
                    int val = m_MQTTClient.Subscribe(STopics, qosLevels);
                }
                catch (Exception ea)
                {
                    MessageBox.Show("订阅失败:" + ea.Message);
                    return false;
                }
                return true;
            }
    
            //发布
            public bool Publish(string strTopic, string strMsg)
            {
                try
                {
                    int val = m_MQTTClient.Publish(strTopic, Encoding.UTF8.GetBytes(strMsg), MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE, false);
                }
                catch (Exception ea)
                {
                    MessageBox.Show("发布失败:" + ea.Message);
                    return false;
                }
                return true;
            }
        }
    }
    

      解决方案资源管理器   -->   引用里增加

    M2Mqtt.Net     xxxxpackagesM2Mqtt.4.3.0.0lib et45M2Mqtt.Net.dll   //这是上面下载的mqtt dll 库

    MQTTnet     xxxxpackagesMQTTnet.3.0.16lib et461MQTTnet.dll     //这是上面下载的mqtt dll 库

    System.Deployment     C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.6.1System.Deployment.dll

    System.Drawing       C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.6.1System.Drawing.dll

    System.Windows.Forms     C:Program Files (x86)Reference AssembliesMicrosoftFramework.NETFrameworkv4.6.1System.Windows.Forms.dll

    创建一个MFC对话框程序测试

    设置   公共语言运行时支持(/clr)

    #using "../debug/xxx.dll"//这里是上面编译出来的dll
    using namespace MQTTLibrary;


    #include<string>
    using namespace std;

    #include <vcclr.h>

    gcroot<MQTTLibrary::MyMQTTClient^> myMqtt;  //声明成全局的变量需要 vcclr.h

     1 void CallBack(System::String ^sTopic, System::String ^sMsg)
     2 {
     3     CString strTopic, strMsg;
     4     strTopic = sTopic;
     5     strMsg = sMsg;
     6     AfxMessageBox(strTopic);
     7     AfxMessageBox(strMsg);
     8 }
     9 
    10 //连接
    11 void CtestMqttDlg::OnBnClickedButton1()
    12 {
    13     // TODO: 在此添加控件通知处理程序代码
    14     myMqtt = gcnew MyMQTTClient();
    15 
    16 
    17     myMqtt->myCallBack = gcnew MyMQTTClient::CallBack(&CallBack);
    18     
    19     CString strIP = _T("127.0.0.1");
    20     int iPort = 61613;
    21     CString strID;
    22     srand((unsigned int)time(NULL));
    23     int num = rand();
    24     strID.Format(_T("mqtt%04d"), num);
    25     CString strUser = _T("admin");
    26     CString strPWD = _T("password");
    27 
    28     System::String ^sIP = gcnew System::String(strIP);
    29     System::String ^sID = gcnew System::String(strID);
    30     System::String ^sUser = gcnew System::String(strUser);
    31     System::String ^sPWD = gcnew System::String(strPWD);
    32 
    33     myMqtt->Connect(sIP, iPort, sID, sUser, sPWD);
    34 }
    35 
    36 //断开
    37 void CtestMqttDlg::OnBnClickedButton2()
    38 {
    39     // TODO: 在此添加控件通知处理程序代码
    40 
    41     myMqtt->Disconnect();
    42 }
    43 
    44 //订阅
    45 void CtestMqttDlg::OnBnClickedButton3()
    46 {
    47     // TODO: 在此添加控件通知处理程序代码
    48     CString strTopic = _T("123");
    49     System::String ^sTopic = gcnew System::String(strTopic);
    50     myMqtt->Subscribe(sTopic);
    51 }
    52 
    53 //发布
    54 void CtestMqttDlg::OnBnClickedButton4()
    55 {
    56     // TODO: 在此添加控件通知处理程序代码
    57 
    58     CString strTopic = _T("123");
    59     CString strMsg = _T("111");
    60     System::String ^sTopic = gcnew System::String(strTopic);
    61     System::String ^sMsg = gcnew System::String(strMsg);
    62     myMqtt->Publish(sTopic, sMsg);
    63 }

    这样就完成了

  • 相关阅读:
    从零开始写STL-容器-双端队列
    JVM 总结
    从零开始写STL-容器-list
    从零开始写STL—容器—vector
    Web 后端编程的几个关键点(总结中...)
    Java Web 总结
    Spring实战读书笔记
    MSDN 同步部分 个人笔记
    洛谷 P3391【模板】文艺平衡树(Splay)
    洛谷 P1503 鬼子进村
  • 原文地址:https://www.cnblogs.com/ckrgd/p/15045505.html
Copyright © 2011-2022 走看看