搜索

VC实现串行通信的动态链接库(DLL)

gecimao 发表于 2019-06-10 12:22 | 查看: | 回复:

  串行通讯口作为计算机与外部串行设备进行数据传输的重要端口,因其使用简单、方便,在业界的各种计算机系统中得到了广泛的应用。由于应用范围很广,软件人员在串行通信方面也积累了丰富的编程经验。关于串行通信的文章不时见于报端,并且还有一些专门讨论

  串行通讯编程的书籍,为软件人员提供了丰富的资源,同时对初次涉足串口编程的软件开发者提供很好的范例帮助。

  虽然关于串口编程的资料很多,但由于工程上需求多种多样,需要根据不同的条件对串口进行灵活控制,在实际应用中,常用的方法有:

  本文是作者在工程实践中根据实际需要,在Visual C++环境中,直接使用Windows提供的API函数实现一个串行通信动态链接库(DLL)的完整实例,实例既给出了DLL函数的编写方法,又包括一份用其它编程工具(VB)对此DLL进行声明及调用的范例。为了使读者一目了然,并减少代码量,本例作了简化,但完全可以运行。希望对需要进行串行通信编程的同行以及需要学习编写DLL的编程爱好者提供一点帮助。

  动态链接库(DLL) 是Windows操作系统的基础,Windows API中的所有函数就是包含在DLL中,它有众多优点,如:简化软件项目管理以便分工合作,有助于节省内存,便于资源共享并且可以用多种语言来编写。

  用VC++ 编写动态链接有以下四种类型:Win32 DLL、MFC常规DLL(动态链接MFC)、MFC常规DLL(静态链接MFC)、MFC扩展DLL等,关于它们之间的区别,在此不一一介绍,可参阅相关文档。本程序的编写为Win32 DLL。

  在Windows系统,系统通过一个叫DCB(Device Control Block)的结构对串行口进行配置,通过Windows API GetCommState函数可以得到串行通讯口的状态信息,使用SetCommState函数可以对串行通讯口进行设置,实现串行通信一般需按以下四步进行:

  (1) 打开串口。由于串口是独占性资源,因此应用程序打开串口后,别的应用程序就不能再打开此串口了。

  (2)配置串口。利用GetCommState函数获取串口当前配置,根据需要更改DCB 结构中的参数,然后用SetCommState函数设置串口通讯参数。

  (3)数据传送。在串口上进行数据发送接收,并根据需要进行校验,触发一些事件等等。这个串口通讯DLL的目的就是收发数据。

  在微软的官方手册中是这样定义CALLBACK函数的:“CALLBACK函数是由应用程序定义而由操作系统调用的函数”。在我们编写DLL时,就是由应用程序定义而由此DLL执行的函数,这一机制在被调用者(DLL)和调用者(应用程序)之间进行信息传递是非常有用的。这一特性,让初学者较难理解,但是它却是编写串行通信程序者的福音,正是由于使用这一特性,才可很方便地在动态链接库中实现MSComm控件中的OnComm 事件,并且可根据需要进行灵活控制。

  以上将一些基础知识进行了适当的介绍,下面再着重讨论怎样编写一个动态链接库(DLL)。

  根据需要,我们在头文件中定义此DLL提供给外部调用的五个输出函数,其定义方法如下:

  DLL的源代码模块需要包含该头文件,若要编写调用该动态链接库函数的C/C++应用程序,也需要包含此头文件。另外,你会发现,MyComDll中包含了extern C链接指示符,这是因为在用C++编写动态链接库时,通常在经C++编译器编译后,其函数名称会改变,如

  ComOpen编译后,展现给调用者的名字是:_ComOpen@8之类,这样应用程序在调用时,链接程序就会抱怨找不到指定的函数。加上extern“C”后,就告诉编译器不要改变变量名或函数名。__declspec(dllimport)是告诉编译器,应用程序将从这个DLL 模块引入这些函数,__declspec(dllexport) 是告诉编译器这些函数是从产生的DLL模块输出给别的应用程序调用。

  此函数用来打开指定的串行通讯口,其参数port即为通讯口号。打开端口后,通过API函数GetCommState得到该端口的配置;根据实际需要,更改其波特率、数据位、停止位等,以及设置触发信号事件的字符(即设置BCB的EvtChar字段);然后通过调用SetCommState设置端口。

  串口打开成功后,创建一个线程ComThreader,在ComThreader中,循环监控串行口是否收到有效数据,若收到则触发回调函数。

  此函数是将指定长度的数据发送到串行口中。其长度由于变量CmdLen指定,发送的数据即为变量Cmd中的内容。发送数据时,需要将线程ComThreader暂时挂起,以避免与接收数据的线程冲突,产生紊乱。

  此函数的功能是设置回调函数,controlport为指定的端口,outfunc是外部应用程序传过来的函数指针,其主要目的是将应用程序的函数指针传给DLL中的一个指针函数,DLL在特定的时刻(本程序是当串行端口接收到有效数据时)通过内部的指针函数,调用外部的应用

  错误提示。Exports节和extern“C”的作用一样,告诉编译器不要改变输出的函数名。

  以下程序示范了在VB中如何调用由VC++编写的动态链接库中的函数。因为动态链接库中使用了回调函数,在VB代码中必须将回调函数放到标准的.BAS模块中,不可放在窗体模块中,也不能将其附加到类模块中。CALLBACK函数只是触发同一工程中一个窗体上的定时器控件,对串口数据进行采集,其定义如下:

  串行通讯的调试相对来说是比较麻烦,在实践中,可以在同一台具有两个串行通讯口的机器上进行调试,只需要将两个串口的RXD和TXD交叉连接,并将5脚对等连接,就可以进行调试了;当然,也可用一个串口进行调试,只需将同一串口的2、3连接。

  在调试过程中,需提醒读者注意的一点是:动态链接库与执行文件应在同一目录下,否则出现找不到动态链接库的问题;由于Windows操作系统本身的原因,在对动态链接库的第一次使用时,须将其拷贝至系统安装目录的system32子目录中才能避免上述问题。

  此DLL是本人在工作中的一点经验积累,去除工程实践中的繁琐枝叶,只涉及串行通讯的关键代码,目的是展示以DLL实现串行通信的方法,希望本文能对读者起到抛砖引玉的作用。

本文链接:http://jonnutting.com/dongtailianjieku/593.html
随机为您推荐歌词

联系我们 | 关于我们 | 网友投稿 | 版权声明 | 广告服务 | 站点统计 | 网站地图

版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright @ 2012-2013 织梦猫 版权所有  Powered by Dedecms 5.7
渝ICP备10013703号  

回顶部