近期准备开始一个新的项目,主要的内容就是制作一个类似于modbus pull 和modbus slave 的windows软件,可以作为modbus的主站和从站,初步设想是实现modbus tcp 的全部功能。计划使用QT 开发图形化界面,调用libmodbus动态库文件。
本项目会放到gitee 地址为:
https://gitee.com/jeasonb/libmodbus
编译动态库计划使用cmake + mingw 实现。
第一步就是从github上拿到libmodbus 的源码使用git bash工具 克隆代码到本地。
git clone https://github.com/stephane/libmodbus.git
拿到代码之后可以看一下目录结构,其中最核心的代码就是src 路径下的几个文件
这篇博客的主要内容就是记录如何将这些文件编译成dll 文件。
第一步就是将需要用到的文件拖到一起,主要就是上图的那些c 文件和对应的头文件。并且创建一个cmake 的配置文件。编写配置文件
cmake_minimum_required(VERSION 3.1 FATAL_ERROR) #
# Set project information
project(libmodbus LANGUAGES C) # 设置语言
include(cmakes/BuildDefaults.cmake) #一些编译选项
include_directories( #添加头文件包含路径
.
./src/
)
add_library(modbus SHARED #关键步骤,设置动态库的文件
./src/modbus-data.c
./src/modbus-tcp.c
./src/modbus-rtu.c
./src/modbus.c
)
target_link_libraries(modbus # 因为是需要依赖socket 所以需要链接windows的socket库
ws2_32.dll
)
add_executable(app #测试的demo 简单的测试函数的功能是否有效
./test/main.c
)
target_link_libraries(app modbus) # 测试代码需要动态链接的库
# src targets.
在进行代码迁移的过程中遇到了以下的几个问题,第一个问题是libmodbus 的版本号 未定义,个人猜测这个应该是会用自动运行脚本去将version.h 文件中指定的字段替换,本人懒得去研究自动生成的脚本,就直接将version.h 中的版本号等 随意改了一下。。。。。。。。。
大致改成这样
/*
* Copyright © 2010-2014 Stéphane Raimbault <stephane.raimbault@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MODBUS_VERSION_H
#define MODBUS_VERSION_H
/* The major version, (1, if %LIBMODBUS_VERSION is 1.2.3) */
#define LIBMODBUS_VERSION_MAJOR 1
/* The minor version (2, if %LIBMODBUS_VERSION is 1.2.3) */
#define LIBMODBUS_VERSION_MINOR 1
/* The micro version (3, if %LIBMODBUS_VERSION is 1.2.3) */
#define LIBMODBUS_VERSION_MICRO 1
/* The full version, like 1.2.3 */
#define LIBMODBUS_VERSION 1
/* The full version, in string form (suited for string concatenation)
*/
#define LIBMODBUS_VERSION_STRING "1.1.1"
/* Numerically encoded version, eg. v1.2.3 is 0x010203 */
#define LIBMODBUS_VERSION_HEX ((LIBMODBUS_VERSION_MAJOR << 16) | \
(LIBMODBUS_VERSION_MINOR << 8) | \
(LIBMODBUS_VERSION_MICRO << 0))
/* Evaluates to True if the version is greater than @major, @minor and @micro
*/
#define LIBMODBUS_VERSION_CHECK(major,minor,micro) \
(LIBMODBUS_VERSION_MAJOR > (major) || \
(LIBMODBUS_VERSION_MAJOR == (major) && \
LIBMODBUS_VERSION_MINOR > (minor)) || \
(LIBMODBUS_VERSION_MAJOR == (major) && \
LIBMODBUS_VERSION_MINOR == (minor) && \
LIBMODBUS_VERSION_MICRO >= (micro)))
#endif /* MODBUS_VERSION_H */
就是给几个宏定义一个值然后是config.h 就是直接在win32 目录下将对应的config.h 导出来。
总体的感觉有一点投机取巧。不过最终还是成功的编译了这个库。测试代码只是简单的调用了一个函数,看一下能不能正常调用到函数。
测试的代码如下:
#include <stdio.h>
#include "../src/modbus.h"
int main(void)
{
modbus_t *m_ctx = modbus_new_tcp("127.0.0.1",502);
if(m_ctx)
{
printf("mctx is created!\r\n");
}else
{
printf("m_ctx is null !\r\n");
}
return 0;
}
关于整个工程,请去gitee 自行下载。更多问题欢迎留言,力所能及范围之内会解答的。
最终的生成文件如下图所示,需要dll 的请到gitee 去下载对应的文件 build 路径下