结对编程(四则运算题目生成器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)每道题目中运算数数量 ...
随机推荐
- HTML页面仿iphone数字角标
做仿iphone样式的数字角标,用简单的css来实现 <html><head><title>角标数字</title><style type=&qu ...
- 2019-8-31-C#-使用汇编
title author date CreateTime categories C# 使用汇编 lindexi 2019-08-31 16:55:58 +0800 2019-2-16 8:56:5 + ...
- Spring MVC 配置Controller详解
在SpringMVC中,对于Controller的配置方式有很多种,如下做简单总结 第一种 URL对应Bean如果要使用此类配置方式,需要在XML中做如下样式配置: <!-- 表示将请求的URL ...
- Oracle varchar2或char类型的byte和char的区别
那其中的BYTE和CHAR有什么区别呢 BYTE,用字节指定:VARCHAR2(10 BYTE).这能支持最多10字节的数据,在一个多字节字符集中,这可能只是两个字符.采用多字节字符集时,字节与字符并 ...
- Docker配置阿里云镜像加速pull
前言:默认Docker拉取镜像是从Docker Hub上拉取,但由于防火墙的原因,导致镜像下载非常慢.为了提高拉取镜像的速度,可以配置阿里镜像或是网易镜像加速,通过使用经验推荐配置阿里镜像. 申请个人 ...
- Qt 样式表鼠标滑过按钮更改Text文本颜色
QSS语法参考http://blog.csdn.net/liang19890820/article/details/51691212 Qt助手上也有比较详细的说明,选择器以及伪选择器,现在只是做个简单 ...
- SEM推广引流效果的因素有哪些呢?
决定搜索引擎推广效果的基本就是流量,所引流过来的是有效流量还是无效流量,直接决定了推广的效果!那我们如何才能引流到最精准的流量把流量变现呢? 第一个就是关键词的匹配模式 "民营企业" ...
- Qt对话框部分学习
一.对话框部分常用内容 颜色对话框.文件对话框.字体对话框.输入对话框.消息对话框.进度对话框.错误对话框.向导对话框. 二.代码部分 //widget.h #ifndef MYWIDGET_H ...
- eureka学习(一)
eureka是一个注册中心,与zookeeper不同的是,eureka是restful格式的调用,zk是rpc,还有就是zk保证一致和容错,eureka则是可用和容错. 使用时首先要加入依赖 < ...
- Comet OJ 茶颜悦色 线段树+扫描线(矩形覆盖最多点+优化)
题目:https://www.cometoj.com/contest/59/problem/D?problem_id=2713 题意:给你一个正方形,然后给你n个点,这个正方形能随意放哪,要求那个正方 ...