在网上,很常见的是VS编译的snmp++库文件,但是本人习惯了使用Qt,并且习惯使用mingw编译器,如果在Qt中使用vs编译器,貌似还需要安装一系列的vs框架,感觉多此一举,因此,便萌生了自己编一个一个mingw库的想法,从结果看,好像也没做什么工作,但是回想这个过程,因为是第一次编译库文件,所以走过的弯路还是非常的多的,折腾了好几天,不过经过这么一倒腾,对于库文件相关的东西,熟悉了很多,这几天的工夫没白花,颇有些得意。
言归正传,开始记录。
Qt的mingw编译器与snmp++瞎折腾之编译篇
一、前期准备
(一)编译环境准备
- 所使用的电脑操作系统,windows10。
- Qt的版本为5.13.1,QtCreator为4.10.1,。
- 编译器为Desktop_Qt_5_13_2_MinGW_64_bit。
(二)源码准备
准备snmp++和des的源码。snmp++就是实现snmp功能的主要代码,des是用来加密算法。
官网下载地址
下载图中所示内容。
然后解压。
二、配置编译环境
(一)工程文件建立
1.新建一个Qt工程文件
- 选择创建C++ Library。
- 命名工程,随意命名,我命名为snmp_dev。
- 选择创建共享库,Shared Library。
- 选择编译器为mingw。
2.将snmp++源代码复制进来
- 打开刚下载后解压的snmp++文件,需要将下属三部分内容复制。
- 先看看include中的内容。可见,snmp__pp文件夹,该文件夹中包含了绝大部分的头文件,将该文件夹复制,粘贴至刚创建的snmp_dev工程目录下。
- 打开src文件,可以看见一堆的cpp文件,将该部分所有的cpp文件,复制到snmp_dev工程目录下。
- 此使,snmp_dev工程文件下,可以看见如下的部分内容,有一部分将在后续过程中,再复制进来。
- 将所有.h和.cpp文件导入工程中。
- 到这一步,导入就暂时告一段落。
3.修改工程文件的一些内容
- 刚创建的snmp_dev工程中,同时生成的有snmp_dev.h与snmp_dev.cpp。下面需要修改这两个文件内容。
- 删除snmp_dev.cpp。
- 修改snmp_dev.h头文件,删除部分内容,添加一个include,修改至如图,务必要修改。
- 至此,就可以点击一下左下角哪个锤子按钮,开始尝试编译了,当然,会有一堆报错,我挨个分析。
(二)漫长的修正bug之路
报错1,“netdb.h:No such file or directory”
-
报错:首先出现的报错如图,对应的libsnmp.cpp文件如图所示:
- 分析:从报错位置来看,百度可知,这部分报错的可能原因,猜测是因为该部分头文件再windows中并不存在,是linux中的内容,不管是不是这个原因,可以确定的是,这几个头文件压根就不存在。
-
解决:头文件不存在,那就不加载就行了,因此,做如下修改:
报错2,“‘in6_addr’was not declared in this scope”
-
报错:接着编译,锤子,然后出现新的问题,这次出现再address.cpp中。
-
分析:分析编译出错的部分的内容,可以猜测,这部分内容是与ipv6相关,关键词搜索宣称的不存在的内容,没找到定义的位置,因此想到,能不能直接不要这部分,因为其实现在我所接触的大部分时候,还用不着IPV6,因此干脆不要了。那如何能让他不编译,看见上面写着ifdef SNMP_PP_IPv6,意思是,如果定义了SNMP_PP_IPv6,就执行下面一部分内容,那直接不定义SNMP_PP_IPv6,不就行了?于是,全局搜索define SNMP_PP_IPv6,果然存在。
- 解决:将上图中的,红框内的内容,注释掉即可,问题解决。
报错3,“openssl/des.h:No such file or directory”
-
报错:这次出问题的是auth_priv.cpp,分析其中内容
- 分析:由报错的内容分析,可以看出来,这一部分是用来加密用的,这个情况很明显,就是却一个des.h头文件,这个头文件很眼熟,没错,在刚刚下载的两个源代码中,解压了snmp++,而另一个libdes一直还没用上,里面就有一个des.h,那是不是复制过来就行?这并不能解决问题,因为可以看见,即便des.h找到了,后面两个人就不存在,因此,问题的根本在于,是否需要使用openssl,实际上是可以不用这个的。
-
解决:因此,根据ifdef _USE_OPENSSL可知,搜索define _USE_OPENSSL。如下图,注释掉红框内的内容即可。
报错4,“des.h:No such file or directory”
-
报错:上一步将openssl给禁用了,新的报错出现了。
- 分析:很明显,就是在将openssl禁用的情况下,这个snmp++有备选方案,备选方案,没错,就是使用libdes,即下载的两个文件,一个snmp++,一个libdes,刚仅仅使用了snmp++,这会将发挥libdes的作用了,在解压libdes后发现,里面有des.h文件。
- 解决:libdes文件夹下,有多个头文件和cpp文件,不晓得需不需要将别的也复制过来,但是,既然报错是des.h文件,那就先解决眼下的问题。复制过来后,编译,这个问题解决了。
报错5,“undefined reference to ‘_imp_htonl’”
-
报错:这只是第一条,出现的不仅仅这条报错。
- 分析:上网百度可以发现,缺失的内容都是一个叫ws2_32的库文件,这是提供了对部分网络相关API的支持的,这个库系统中会自带,因此,只需要引入即可。
-
解决:在.pro文件中添加 LIBS += -lws2_32,问题解决。
报错6,“undefined reference to ‘des_key_sched’”
-
报错:又出现新的报错。
- 分析:undefined,意思肯定是缺少了一些库文件或者什么内容的调用。再观察到缺少的东西的名字,里面有一个des的字眼,猜测估计就是缺少了libdes文件夹下的内容。
-
解决:不知道缺的是哪个,一不做二不休,把libdes下的所有.h和.c都复制过来,编译,问题果然解决。
复制的位置关系如下,该图在上文中已经出现过了,当时笔者为了省事,没有删除des的部分内容:
(三)编译结果
1.查看编译生成的内容
图中点选即生成的内容,.a和.dll库文件,即开发所需的.a文件,和运行过程中需要的.dll文件。
三、注意事项
- 一定要搞清楚头文件和cpp文件等存放的位置,报错各个头文件的拓扑关系,这在后续的库文件的使用中,尤其重要。
- 编译过程中,缺什么别慌,冷静分析,看能不能找不到,同时也得注意看代码,分析是否可以跳过该部分内容。
- 注意关注点,生成库文件的工程文件,比如我所用的例子中的,snmp_dev.h和snmp_dev.cpp文件,一定记得删除cpp文件,然后在.h文件中,将原来的内容全清空了,主要指的是原有的class等内容,只需要引入#include snmp/snmp_pp.h即可。如原有的class等内容不清空,编译中虽然不报错,但是编译出的.a文件就是空文件,无法使用。
- 编译结果的.a和.dll文件,区别在于.a是程序编译生成所需,.dll是程序运行所需的。
四、资源共享
光说不给,那是耍流氓。