VS2019编译EPANET2.0源代码生成和调用DLL动态链接库

实习时需要在Epanet源码中添加新函数并在自己实现的QGIS插件中调用,在生成和调用dll过程中遇到了一些问题,记录下这些问题和解决过程。


生成DLL文件和LIB文件

1. epanet源代码

我是下载的同济大学的汉化版,代码比较简洁一些
下载地址:EPANETH2中文版

2.创建动态链接库

打开VS2019,创建新项目,选择动态链接库
在这里插入图片描述
将EPANETH2源代码中所有头文件和源文件放入项目中
在这里插入图片描述
直接生成解决方案会报一些错误,需要进行下面两个设置
项目属性->C/C+±>预编译头,设置不使用预编译头
在这里插入图片描述
项目属性->C/C+±>预处理器,在预处理器定义里添加 _CRT_SECURE_NO_DEPRECATE
在这里插入图片描述

3.编译动态链接库

生成解决方案后,在项目的Release文件夹下生成了dll文件。在其他项目中进行显示调用,通过LoadLibrary函数调用dll时成功,通过GetProcAddress函数获取EPANET.dll中的方法却失败了
打开VS2019命令提示符
在这里插入图片描述
定位到dll文件所在目录路径,输入dumpbin /exports dll文件名,可以看到dll文件没有导出函数接口
在这里插入图片描述
发现在预处理器定义里没有DLL,只有_USERDLL
将toolkith.h中定义DLLECPORT代码第一个#ifdef DLL改为预处理器定义中存在的#ifdef _USERDLL
在这里插入图片描述
再次通过命令提示符查看dll的函数接口
在这里插入图片描述
接口是完整的,自己新写的函数接口也有。接下来在项目中再次调用试试


在项目中调用

1.控制台应用调用EPANET动态链接库文件

显示调用dll是成功的,但是在隐式调用时头文件epanet2h.h报错,无法运行
在这里插入图片描述
对epanet2h.h进行一些修改
在这里插入图片描述
在工具箱函数声明部分添加extern “C”{ }

// --- 声明EPANET工具箱函数
extern "C" {
    int   DLLEXPORT ENepanet(char*, char*, char*, void (*) (char*));
    int   DLLEXPORT ENopen(char*, char*, char*);
    int   DLLEXPORT ENsaveinpfile(char*);
    int   DLLEXPORT ENclose(void);

    int   DLLEXPORT ENsolveH(void);
    int   DLLEXPORT ENsaveH(void);
    int   DLLEXPORT ENopenH(void);
    int   DLLEXPORT ENinitH(int);
    int   DLLEXPORT ENrunH(long*);
    int   DLLEXPORT ENnextH(long*);
    int   DLLEXPORT ENcloseH(void);
    int   DLLEXPORT ENsavehydfile(char*);
    int   DLLEXPORT ENusehydfile(char*);

    int   DLLEXPORT ENsolveQ(void);
    int   DLLEXPORT ENopenQ(void);
    int   DLLEXPORT ENinitQ(int);
    int   DLLEXPORT ENrunQ(long*);
    int   DLLEXPORT ENnextQ(long*);
    int   DLLEXPORT ENstepQ(long*);
    int   DLLEXPORT ENcloseQ(void);

    int   DLLEXPORT ENwriteline(char*);
    int   DLLEXPORT ENreport(void);
    int   DLLEXPORT ENresetreport(void);
    int   DLLEXPORT ENsetreport(char*);

    int   DLLEXPORT ENgetcontrol(int, int*, int*, float*,
        int*, float*);
    int   DLLEXPORT ENgetcount(int, int*);
    int   DLLEXPORT ENgetoption(int, float*);
    int   DLLEXPORT ENgettimeparam(int, long*);
    int   DLLEXPORT ENgetflowunits(int*);
    int   DLLEXPORT ENgetpatternindex(char*, int*);
    int   DLLEXPORT ENgetpatternid(int, char*);
    int   DLLEXPORT ENgetpatternlen(int, int*);
    int   DLLEXPORT ENgetpatternvalue(int, int, float*);
    int   DLLEXPORT ENgetqualtype(int*, int*);
    int   DLLEXPORT ENgeterror(int, char*, int);

    int   DLLEXPORT ENgetnodeindex(char*, int*);
    int   DLLEXPORT ENgetnodeid(int, char*);
    int   DLLEXPORT ENgetnodetype(int, int*);
    int   DLLEXPORT ENgetnodevalue(int, int, float*);

    int   DLLEXPORT ENgetlinkindex(char*, int*);
    int   DLLEXPORT ENgetlinkid(int, char*);
    int   DLLEXPORT ENgetlinktype(int, int*);
    int   DLLEXPORT ENgetlinknodes(int, int*, int*);
    int   DLLEXPORT ENgetlinkvalue(int, int, float*);

    int   DLLEXPORT ENgetversion(int*);

    int   DLLEXPORT ENsetcontrol(int, int, int, float, int, float);
    int   DLLEXPORT ENsetnodevalue(int, int, float);
    int   DLLEXPORT ENsetlinkvalue(int, int, float);
    int   DLLEXPORT ENaddpattern(char*);
    int   DLLEXPORT ENsetpattern(int, float*, int);
    int   DLLEXPORT ENsetpatternvalue(int, int, float);
    int   DLLEXPORT ENsettimeparam(int, long);
    int   DLLEXPORT ENsetoption(int, float);
    int   DLLEXPORT ENsetstatusreport(int);
    int   DLLEXPORT ENsetqualtype(int, char*, char*, char*);
    int   DLLEXPORT OpenGisData(char*, int);
}

再次测试在项目中调用
在这里插入图片描述
通过控制台打印信息可以看到调用成功了
在这里插入图片描述

2. QGIS插件中调用EPANET动态链接库文件

我的QGIS插件是C++实现的
把dll放在插件动态链接库项目的Release文件夹中,在项目属性->C/C+±>常规->附加包含目录添加epanet.h所在文件夹目录,项目属性->链接器->常规->附加目录库中添加lib文件所在文件夹目录,项目属性->链接器->输入->附加依赖项添加lib
在我的QGIS插件中显示调用dll,QGIS插件dll文件放入QGIS的plugins中,在QGIS中测试没有反应,隐式调用插件则直接失效
同时将epanet生成的dll放在plugins目录中,可以成功调用了
![在这里插入图片描述](https://img-blog.csdnimg.cn/c73c5356c96f4dec9fc99ff48c1b210c.p

参考文章:
https://blog.csdn.net/xingbaoqiliaozhan/article/details/107837653
https://blog.csdn.net/zhanglifu3601881/article/details/80666755
https://zhuanlan.zhihu.com/p/146546063
https://blog.csdn.net/cnhk1225/article/details/76167469

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

打工人没有魂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值