结对编程(四则运算题目生成器core第七组)对接心得
在这篇博客博主想记录一下此次结队编程作业中与ui组对接的心得。在这里我也想表达一下对涂涵越同学的敬佩,他遇到困难时孜孜不倦求解的毅力着实让我佩服,我们在dll的生成上遇到了很大的困难,要不是他的坚持我们可能就换用类接口,或者两方都碰壁了。能够遇到这样一位治学态度这么好、很负责任的搭档真的是非常幸运啊。接下来我主要从两方面讲一下自己的心得体会。
1. DLL封装
(1)stl接口的实现:在dll接口中传递stl(标准模板库)类型和容器时非常麻烦的事情,不管是生成还是使用起来都有很多陷阱。一开始我们在头文件中输入函数声明时,返回类型是string、string*、 map的地方都报了错,我们的程序中有两个比较复杂的自定义类,其中一个还使用了友元函数和重构运算符,如果dll真如网上大多数博客所说,只支持C接口,那问题就变得相当棘手了。幸运的是,dll并不是不支持stl的,但是写stl的接口方法比较复杂。微软官方给出的解释是:
Most classes in the Standard C++ Libraries use static data members directly or indirectly. Since these classes are generated through template instantiation, each executable image (usually with DLL or EXE file name extensions) will contain its own copy of the static data member for a given class. When a method of the class that requires the static data member is executed, it uses the static data member in the executable image in which the method code resides. Since the static data members in the executable images are not in sync, this action could result in an access violation or data may appear to be lost or corrupted.
(我的翻译:标准库中的大部分类都直接或间接地使用静态的数据成员。 由于这些类是通过模板实例化产生的,每个可执行的像文件(一般是.dll或.exe文件)会复制每一个类中的静态数据成员。当需要类中需要用到这些静态数据成员的方法即将被执行时,这个方法会使用方法代码所在的或所对应的像文件中的静态数据成员。由于像文件中的这些静态数据成员不同步(应该是指不和生成它的初始文件同步), 调用这个方法可能会导致访问失败,或者系统会提示数据丢失或被损坏。)
根据这个提示,我们将类的定义,包括其数据成员的定义及初始化、成员函数的声明写在头文件中,然后在cpp文件include该头文件, 编写函数体(需加上“类名::”),并直接引用该自定义类。点击生成解决方案,就可以成功生成lib文件和dll文件。
以我们用于生成题目的arithmetic类为例,在头文件中,我们定义数据成员和成员函数(方法)如下:
class ArithmeticAPI arithmetic {
private:
typedef struct expNode {
string exp;
string ans;
}expNode;
expNode *p;
int expNum;
int expType; //0 for integers, 1 for decimals, 2 for fractions
int oprNum;
int oprType[5]; //0 for +-, 1 for +-x/, 2 for +-x/^
int min, max;
int accuracy; //the accuracy of decimals public:
arithmetic() { expNum = 1;
expType = 0;
oprNum = 1;
oprType[0] = 1;
oprType[1] = 1;
oprType[2] = 0;
oprType[3] = 0;
oprType[4] = 0;
min = 1;
max = 10;
accuracy = 2; } void setExpNum(int n);
void setExpType(int n);
void setOprNum(int n);
void setOprAdd(int n);
void setOprSub(int n);
void setOprMul(int n);
void setOprDiv(int n);
void setOprPow(int n);
void setOprAll(int a, int s, int m, int d, int p);
void setOprByStr(string s);
void setBounds(int min, int max);
void setAccuracy(int n); int getExpNum(); string* getExpSet(); string* getAnsSet(); void generate();
};
在cpp文件中则完成函数体的编写:
#include"7_ArithmeticDll.h"
/* Member functions of arithmetic class */
void arithmetic::setExpNum(int n) { try {
expNum = n;
if (expNum < ) {
throw "The number of expressions must be an integer and at least one.";
}
}
catch (const char* msg) {
cout << msg << endl;
setExpNum();
}
} void arithmetic::setExpType(int n) {
try {
expType = n;
if (expType > || expType < ) {
throw "Type of expressions must be an integer among 0, 1 and 2.";
}
}
catch (const char* msg) {
cout << msg << endl;
expType = ;
setExpNum();
} }
(2)宏定义API接口
#ifndef ArithmeticDLL
#define ArithmeticAPI __declspec(dllexport)
#else
#define ArithmeticAPI __declspec(dllimport)
#endif
在cpp文件中#define ArithmeticDLL ,这样的话在头文件中引用ArithmeticAPI,就是__declspec(dllexport)(输出)。调用方在不#define ArithmeticDLL, 则其引用 ArithmeticAPI的话,对应的就是__declspec(dllimport)(输入)。
(3)DLL工程:不同版本的Visual Studio支持的dll工程或可以生成dll的工程使用方法不同,有一些工程需要手动添加模块定义文件(带.def扩展名)才能生成lib文件。我之前使用的是VS2015,把网上推荐的方法都试了一遍,也没有正确生成dll和lib文件,我的搭档用的是VS2017,直接建立一个DLL工程,经过以上步骤就可以了。以下是VS2017的新建工程界面:
(4)dll的使用:摘抄自我们的API文档
· 将7_ArithmeticDll.dll,7_ArithmeticDll.lib以及7_ArithmeticDll.h 三个文件 复制到存放即将调用core的.cpp的文件夹中
· 在头文件中添加 现有项 "7_ArithmeticDll.h"
· 在资源文件中 添加 现有项 "7_ArithmeticDll.lib"
· 在用来调用core的.cpp中添加 #include"7_ArithmeticDll.h"
· release/debug、x64/x86不能混用
2.参数的传递
为了设置题目生成器,需要传递许多参数,从上面arithmetic类的定义可以看到,需要设置的参数有
int expNum;
int expType; //0 for integers, 1 for decimals, 2 for fractions
int oprNum;
int oprType[5];
int min, max;
int accuracy; //the accuracy of decimals
我们觉得一个子程序(函数)传递这么多参数不易于使用,出错率比较高,所以将各个参数的设置分散到各个set函数中(在上面代码中可以看到),同时为各个参数赋予了比较合理的默认值。
生成题目后,我们将题目存在string数组中并返回string数组的指针(string*类型),后来我们才知道用Qt框架开发UI的同学需要将string类转为Qstring类, 这一点说明我们在接口通用性上考虑还是欠妥当。另外,关于运算符类型的设置,各组core各执一词,有一些组可以任意选择,而我们是选择向下兼容,并且提供了不止一个设置方式,以满足ui的需要。
经过这次和UI组的对接,我觉得接口提供方和调用方一定要保持良好的沟通,不然会导致双方都付出额外的时间。
结对编程(四则运算题目生成器core第七组)对接心得的更多相关文章
- 20175226 2018-2019-2《java程序设计》结对编程-四则运算(第一周-阶段总结)
结对编程-四则运算(第一周-阶段总结) 需求分析 实现一个四则运算程序,要求: 自动随机生成小学四则运算题目(加,减,乘,除) 支持整数.真分数且支持多项式 能够利用栈的思想,将中缀转换为后缀表达式 ...
- 20175305张天钰Java结对编程四则运算(二)
Java结对编程四则运算(二) 一.题目描述及要求 Git提交粒度不要太粗,建议一个文件/一个类/一个函数/一个功能/一个bug修复都进行提交,不能一天提交一次,更不能一周一次,参考Commit Me ...
- 20175305张天钰Java结对编程四则运算
Java结对编程四则运算 一.题目描述:如何对表达式进行求值运算呢 1.中缀表达式与后缀表达式(娄老师讲解) 中缀表达式就是运算符号在运算数中间的表达式,比如1+2,顾名思义,后缀表达式就是运算符在运 ...
- 结对编程--四则运算(Java)萧英杰 夏浚杰
结对编程--四则运算(Java)萧英杰 夏浚杰 Github项目地址 功能要求 题目:实现一个自动生成小学四则运算题目的命令行程序 使用 -n 参数控制生成题目的个数(实现) 使用 -r 参数控制题目 ...
- 结对编程--四则运算(Java)梅进鹏 欧思良
结对编程--四则运算(Java)梅进鹏 欧思良 Github项目地址:https://github.com/MeiJinpen/Arithmetic 功能要求 题目:实现一个自动生成小学四则运算题目的 ...
- 王译潇20162314 实验报告三plus结对编程四则运算第一阶段
北京电子科技学院BESTI实验报告 课程:程序设计与数据结构 班级: 1623 姓名: 王译潇 学号:20162314 指导教师:娄佳鹏老师.王志强老师 实验日期:2017年5月12号 实验密级: 非 ...
- Java结对编程四则运算一周小结
Java结对编程四则运算一周小结 需求分析 对于四则运算来说最主要的就是要计算出产生的式子(字符串的形式). 设计思路 总体可将这个项目分解为几个部分:产生式子,计算式子,判断对错并记录: 具体的思路 ...
- 结对编程1 —— 基于GUI和Swing的四则运算题目生成器
合作伙伴 201421123102 王艳秋 201421123106 陈 雄 代码地址 题目描述 我们在个人作业1中,用各种语言实现了一个命令行的四则运算小程序.进一步,本次要求把这个程序做成GUI( ...
- 佛系结对编程---四则运算(Core 第四组)
----by core 第四组 ( 邹卫其 范力 ) 一. 项目介绍 1. 能自动生成小学四则运算题目并给出答案,生成题目时可以选择下列参数: 1)生成题目数量 2)每道题目中运算数数量 ...
随机推荐
- Java使用Jsoup简单解析页面
jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址.HTML 文本内容.它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出 ...
- LLppdd likes strings
LLppdd's likes strings! Time Limit: 1 s Memory Limit: 256 MB 题目背景 LLppdd 由于实在是太弱了,在 \(ION 2018\) 模拟十 ...
- cmd 编码格式
相当于编辑器的声明为gbk格式编码,输出格式也是gbka = '中文' 就会以gbk编码为str,也只能以gbk解码. reload sys修改默认编码 在不指定编码的时候充当默认解码或者编码格式
- 从vue的组件传值着手浅谈观察者模式
首先,提到观察者模式,这不禁让我想到了MVVM,MVVM架构模式感觉用到了观察者的思想. 我们还是按照惯例,了解一下什么是观察者模式 观察者模式,类似发布订阅模式,完成这个动作首先最少得有两个不同的对 ...
- go语言从例子开始之Example18.struct结构体
Go 的结构体 是各个字段字段的类型的集合.这在组织数据时非常有用 Example: package main import "fmt" type product struct{ ...
- java 逻辑运算符
/* 与(并且) && 全部是true 否则就是false 或(或者) ||至少有一个是true ,就是true 全部是false 才是faalse 非(取反) ! 本来是true,变 ...
- vue-router中的router-link的active-class
vue-router中的router-link的active-class 在vue-router中要使用选中样式的方法有两种: 1.直接在路由js文件中配置linkActiveClass 2.在r ...
- js判断元素是否可见
dom元素是否可见可使用jq的is方法和dom的offsetParent === null方法 jq中 $(element).is(":visible") === true !!( ...
- 双联通的tarjan算法
转自:https://www.zhihu.com/question/40746887/answer/88428236 连通分量有三种∶边双连通分量,点双连通分量,强连通分量,前两种属于无向图,后一种属 ...
- Nacos 1.1.4 发布,业界率先支持 Istio MCP 协议
Nacos是阿里巴巴开源的服务发现与配置管理项目,本次发布的1.1.4版本,主要带来的是与Istio的对接功能,使用的是Istio最新的MCP协议.本文将介绍包括这个功能在内的新版本发布的功能. 升级 ...