该篇是接续上一篇编译相关的文章后的使用篇,因此,该篇默认使用的结果为上两篇编译产生的结果。
动态库传送门:《撮合Qt的mingw编译器与snmp++3.4.6之源码编译动态库》
动态库传送门:《撮合Qt的mingw编译器与snmp++3.4.6之源码编译静态库》
为保证读者阅读的连续性,可操作性,建议先行阅读上一篇内容。
撮合Qt的mingw编译器与snmp++3.4.6之库文件使用
一、搞清楚我们有什么库文件以及放在哪
可以看到,拿到手的,自己编译生成的库文件。如图放置
1.动态库文件
动态库文件。有两个,一个是snmp_dev.a,一个是snmp_dev.dll,以及相应的头文件。我们将这两个库文件放在同一个文件夹下,比如创建一个名为lib的文件夹。将该文件夹放置在需调用snmp功能的工程文件的目录下。同时,创建一个名为include的文件夹,将头文件放进该文件夹下,将include文件夹也放置在该工程目录下。snmp_dev.a是为了编译使用,snmp_dev.dll是为了程序运行使用,没有.dll库文件,exe文件无法运行。因此在发布时,需要将snmp_dev.dll文件复制到与exe同个目录下。
2.静态库文件
静态库文件的编译。只有一个snmp_static.a文件,以及相应的头文件。同样,将snmp_static.a放在lib文件夹下,将头文件放在include文件夹下。
二、库文件及头文件的导入
- 选择“添加库”
- 选择“外部库”
- 静态库的导入如下选择,勾选静态:
- 动态库的导入,勾选动态,如下选择:
三、进一步修改pro文件
这一步,只需要静态库做就行,静态库需要在pro文件中,再添加
LIBS += -lws2_32
上述操作动态库不需要。
四、注意点(重点)
-
搞清楚include再Qt过程中意味着什么,在pro文件中,include的文件,可以在工程文件中直接调用,直接使用#include "xxx.h"或者下面还有二级文件夹,则写作#include “/xxxx/xxx.h”。其实也可以不适用include文件的方式写入,使用include,就是不需要将这些文件导入到工程文件的目录中去,就能直接使用,不然的话,就需要将所有的,需要使用到的头文件,通过“添加现有文件”或者“Add Existing Directory”导入到目录下。比如我在上述目录下,就需要在pro文件中添加如下内容,当然如果是通过的“添加库”功能添加的,这一个会自动添加上去,无需手动添加,只需要检查一下:
INCLUDEPATH += $$PWD/include
-
搞清楚上面一点后,调用库文件一定要注意的一点,务必注意的一点,就是头文件的导入,头文件的调用,或者世界使用include,如此的话,只要头文件之间互相的拓扑关系不变,在工程文件中都可以直接使用#include "xxx.h"导入,如果不用include,就得将头文件放置在编译库文件时相同的位置再导入到该工程文件中。这个是一定要梳理清楚的,不然会出现头文件找不到库文件的对应函数的情况。
-
因此,建议通过添加一个include文件夹的方式,添加头文件。
-
调用的方式,可以直接在需要的地方调用一个总的入口函数,如在我的工程中.
静态调用为:#include <snmp_static.h>
动态调用为:
#include <snmp_dev.h>
-
有时候添加以后还不能正常使用的,可能是因为命名空间的原因,这个时候,需要在调用的文件内,指定命名空间,如下:
using namespace Snmp_pp;
-
在程序发布时,如果使用的静态库,则无特别操作,如果使用的动态库,则需要将dll文件复制到与exe文件同一个目录下。
五、测试代码
MyStringArray.h:
#include <vector>
#include<QString>
class MyStringArray
{
public:
MyStringArray();
virtual ~MyStringArray();
public:
std::vector<QString> OidStr; //保存OID的数组;
std::vector<QString> Value; //保存值得数组;
QString err;
public:
void GetTree(QString &ip, QString &community, QString &oid_str); //检索一个子树的全部snmp变量,对应的OID以及值保存到数组中;
void GetOne(QString &ip, QString &community, QString &oid_str, QString &reply); //取回单个指定OID的snmp变量的值;
bool GetTwo(QString &ip, QString &community, QString &oid1, QString &oid2, unsigned long &r1, unsigned long &r2);
void GetNextOne(QString &ip, QString &community, QString &oid_str, QString &reply);//取回指定OID的字典下一个snmp变量的值;
void Add(QString &s_Oid, QString &s_Value); //数组中增加项,两个数组同时分别增加OID和值;
QString GetOid(int index); //获得指定索引处的OID字符串;
QString GetValue(int index); //获得指定索引处的值字符串;
void SetValue(int index, QString Str); //设置指定索引处的值字符串;
int GetCount(); //获得数组中元素的个数;
void clear(); //清除数组;
};
MyStringArray.cpp(仅展示部分内容):
#include <QMessageBox>
#include "MyStringArray.h"
#include <snmp_dev.h>
using namespace Snmp_pp;
void MyStringArray::GetTree(QString &ip, QString &community, QString &oid_str)
{
clear();
char oid_char[100];
strcpy(oid_char,oid_str.toStdString().c_str());
char ip_char[100];
strcpy(ip_char,ip.toStdString().c_str());
Snmp::socket_startup();
UdpAddress address(ip_char);
address.set_port(161); //构造一个地址对象;
Oid Baseoid(oid_char); //构造一个OID对象;
snmp_version version = version2c;
int status;
Snmp snmp(status, 0, false); //构造一个snmp对象;
Pdu pdu;
Vb vb;
vb.set_oid(Baseoid);
pdu += vb;
CTarget ctarget(address);
ctarget.set_version(version);
ctarget.set_retry(1);
ctarget.set_timeout(100);
char community_char[100];
strcpy(community_char,community.toStdString().c_str());
ctarget.set_readcommunity(community_char); //构造一个CTarget并设置相应参数;
SnmpTarget *target;
target = &ctarget;
Oid NextOid(Baseoid);
NextOid += ".1";
QString reply_oid;
QString reply_value;
while (Baseoid.nCompare(Baseoid.len(), NextOid) == 0) //如果NextOid以Baseoid开始,进行getnext操作;
{
//status = snmp.get_next(pdu, *target);
status = snmp.get(pdu, *target);
if (status == SNMP_CLASS_SUCCESS)
{
pdu.get_vb(vb, 0); //取出第一个VB;
//vb.get_oid(NextOid); //取出返回的OID,存放到NextOid;
reply_oid = vb.get_printable_oid();
reply_value = vb.get_printable_value();
if (reply_value.length() == 0)
reply_value = "NULL"; //如果操作成功取出返回的OID以及值;
if (Baseoid.nCompare(Baseoid.len(), NextOid) == 0)
{
reply_oid.trimmed();
reply_value.trimmed();
if(reply_value.compare("NULL")!=0)
{
OidStr.push_back(reply_oid); //保存OID串到数组中;
Value.push_back(reply_value); //保存值到数组中;
}
}
}
else
{
//QMessageBox::information(this, ("读取操作失败,请检查配置!"), "error", QMessageBox::NoButton);
return;
}
snmp.get_next(pdu, *target);//
pdu.get_vb(vb, 0); //取出第一个VB;
vb.get_oid(NextOid); //取出返回的OID,存放到NextOid;
vb.set_oid(NextOid);
vb.set_null();
pdu.set_vb(vb, 0); //重新设置vb,准备进入下一循环;
}
Snmp::socket_cleanup();
}
可通过上述内容进行测试,最简单的方法是看编译能否通过。
另外,也可通过文章开端给出的两个链接中,有下载工程文件的链接,下载直接测试。