{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 序言"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. IDE工具\n",
" - VSCode\n",
" - 语法检测:头文件(include头文件) + 编译内置的语法\n",
" - 添加头文件检测:ctrl + shift + p->C++配置编辑,添加头文件所在目录;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. 控制终端\n",
" - 命令\n",
" - 环境变量\n",
" - PATH: echo %PATH%\n",
" - set指令显示所有环境变量\n",
" - PATH:window执行程序的搜索的路径;每个路径使用`;`分号分隔\n",
" - 有可视化的设置的"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3. VisualStudio 开发环境的设置\n",
" - 使用脚本的文件来设置,脚本是vcvars64.bat\n",
" - 设置vcvars64.bat的目录到PATH环境变量;\n",
" - `PATH=C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Enterprise\\VC\\Auxiliary\\Build`\n",
" - 使用可视化设置环境变量,需要重启终端;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"4. 开发工具 \n",
" - cl 编译器\n",
" - link 连接器 (PE格式)\n",
" - lib 库归档工具(静态库:目标文件的归档)\n",
" - dumpbin PE与目标文件格式分析工具"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 工程组织与编译器"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. 编译器\n",
" - `cl 源代码吗` 编译/链接为执行文件\n",
" - `/EHsc`\n",
" - `/MD`\n",
" - `/utf-8`\n",
" - `/source-charset:utf-8`\n",
" - `/execution-charset:utf-8`\n",
" - 头文件目录"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. 说明:\n",
" - 第一次你输出,汉字可能是乱码\n",
" 1. 使用chcp命令改变终端的代码页。utf-8的code page= 65001\n",
" - `chcp 65001`\n",
" 2. 在区域/语言中直接设置编码(整个系统设置为utf-8)\n",
" - opencv不识别中文目录;(系统设置编码)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3. 链接器\n",
" - link\n",
" - cl负责编译 : 检测语法,生成目标文件\n",
" - link负责链接:负责生成PE格式文件,需要信息动态库信息\n",
" - link 选项 目标文件s\n",
" - `/out`\n",
" - `/MACHINE:X64`\n",
" - 第三方的库的库目录\n",
" - 第三方的库名"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 静态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 前提:lib/dll这两个文件解释清楚;\n",
" - lib:静态库\n",
" - dll:动态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 实现一个库函数"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- `gk_math.h`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#ifndef GK_MATH_H\n",
"#define GK_MATH_H\n",
"extern int gk_add(int, int);\n",
"#endif\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- `gk_maath.cpp`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include \"gk_math.h\"\n",
"\n",
"int gk_add(int p1, int p2){\n",
" return p1 + p2;\n",
"}\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 编译成静态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```bash\n",
"@rem 静态库的编译\n",
"@rem 编译\n",
"@cl /c /EHsc /MD /nologo /source-charset:utf-8 /execution-charset:utf-8 /Fo:gkmath.obj gk_math.cpp\n",
"@rem 静态库链接\n",
"lib /MACHINE:X64 /nologo /OUT:gkmath.lib gkmath.obj\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 代码的组织"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 使用shell脚本或者bat处理脚本,比较麻烦的是多个操作需要写成多个bat文件;实际引入一个专门的工程组织脚本Makefile;"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 工程组织的方式:\n",
" - 通用\n",
" - Makefile\n",
" - CMake\n",
" - QMake\n",
" - 个性化:\n",
" - Visual Studio\n",
" - Qt Creator\n",
" - QMake\n",
" - Eclipse C++\n",
" - C++ Builder"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Makefile脚本的语法:Makefile\n",
" 1. 定义变量\n",
" 2. 任务(Task)\n",
" - 依赖(任务依赖另外一任务)\n",
" 3. 指令"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- Makfile例子"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```bash\n",
"CL_FLAGS = /c \\\n",
"\t\t /EHsc \\\n",
"\t\t /MD \\\n",
"\t\t /nologo \\\n",
"\t\t /source-charset:utf-8 \\\n",
"\t\t /execution-charset:utf-8\n",
"\n",
"LINK_FLAGS = /MACHINE:X64 \\\n",
"\t\t /nologo\n",
"\n",
"OBJS = gkmath.obj\n",
"SOURCES = gk_math.cpp\n",
"TARGETS = gkmath.lib\n",
"\n",
"main:$(TARGETS) main.cpp\n",
"\t@ cl /nologo /MD /Fe:main.exe main.cpp $(TARGETS) \n",
"\n",
"$(TARGETS):$(OBJS)\n",
"\t@lib $(LINK_FLAGS) /OUT:$(TARGETS) $(OBJS)\n",
"\n",
"$(OBJS): gk_math.h gk_math.cpp\n",
"\t@cl $(CL_FLAGS) /Fo:$(OBJS) $(SOURCES)\n",
"\n",
"\n",
"clean:\n",
"\t@del *.exe *.obj *.lib 2>/Nul\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 使用静态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. 在链接的时候使用静态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include <stdio.h>\n",
"#include \"gk_math.h\"\n",
"int main(int argc, char **argv, char **arge){\n",
" printf(\"C++程序编程!静态库调用结果:%d\\n\", gk_add(45, 55));\n",
" return 0;\n",
"}\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 编译脚本\n",
"\n",
"-----\n",
"\n",
"```bash\n",
"CL_FLAGS = /c \\\n",
"\t\t /EHsc \\\n",
"\t\t /MD \\\n",
"\t\t /nologo \\\n",
"\t\t /source-charset:utf-8 \\\n",
"\t\t /execution-charset:utf-8\n",
"\n",
"LINK_FLAGS = /MACHINE:X64 \\\n",
"\t\t /nologo\n",
"\n",
"OBJS = gkmath.obj\n",
"SOURCES = gk_math.cpp\n",
"TARGETS = gkmath.lib\n",
"\n",
"main:$(TARGETS) main.cpp\n",
"\t@ cl /nologo /MD /Fe:main.exe main.cpp $(TARGETS) \n",
"\n",
"$(TARGETS):$(OBJS)\n",
"\t@lib $(LINK_FLAGS) /OUT:$(TARGETS) $(OBJS)\n",
"\n",
"$(OBJS): gk_math.h gk_math.cpp\n",
"\t@cl $(CL_FLAGS) /Fo:$(OBJS) $(SOURCES)\n",
"\n",
"\n",
"clean:\n",
"\t@del *.exe *.obj *.lib 2>/Nul\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. 在代码中使用静态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include <stdio.h>\n",
"#include \"gk_math.h\"\n",
"\n",
"#pragma comment(lib, \"gkmath.lib\")\n",
"\n",
"int main(int argc, char **argv, char **arge){\n",
" printf(\"C++程序编程!静态库调用结果:%d\\n\", gk_add(45, 55));\n",
" return 0;\n",
"}\n",
"// cl /nologo /MD /Fe:main.exe main_lib.cpp\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 编译命令:\n",
" - `cl /nologo /MD /Fe:main.exe main_lib.cpp`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"-------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 回顾\n",
" 1. 开发工具\n",
" 1. cl编译器 mac: clang/c++, posix: gnu g++, hp:acc: intel:cc, sun:cc\n",
" - 默认是调用Link默认链接\n",
" -/link 后面直接包含link选项\n",
" \n",
" 2. link连接器(posix:ld)\n",
" -link步骤很多编译器中默认自动调用\n",
" 3. lib(ar)\n",
" -静态库\n",
" 4. dumpbin(nm)\n",
" -分析目标文件与PE执行文件\n",
" 5. nmake(make)\n",
" -nmake task\n",
" -nmake task -f makefile文件\n",
" 2. vcvars64.bat / vcvars32.bat\n",
" - 空格转义:“D:\\Program Files (x86)”\n",
" 3. makefile的语法\n",
" - 任务目标:依赖\n",
" -指令(使用tab开始)\n",
" - 伪任务目标:\n",
" -文件不存在\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"--------------"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 动态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 实现代码"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1.h文件"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include \"gkmath.h\"\n",
"\n",
"int gk_add(int p1, int p2){\n",
" return p1 + p2;\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.cpp文件"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include \"gkmath.h\"\n",
"\n",
"int gk_add(int p1, int p2){\n",
" return p1 + p2;\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 编译动态库"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 准备:link选项\n",
" - /DLL\n",
" - /IMPLIB : 按指定连接的时候产生导入的符号,使用lib静态库的方法存放:\n",
" - /EXPORT : 指定哪些函数可以被别人调用 = /DEF :DEF导出函数\n",
" - /MACHINE :指定CPU结构X64/X86/ARM/ARM64/EBC\n",
" - /OUT: 指定输出文件名,dll输出名字"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 编译脚本"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```bash\n",
"# 编译选项设置一个变量\n",
"CL_ARGS = /EHsc /MD /source-charset: utf-8 /execution-charset:utf-8 /nologo \n",
"# 链接选项设置一个变量\n",
"LINK_ARGS = /MACHINE:X64 /NOLOGO /DLL\n",
"\n",
"# 文件设置成变量\n",
"SOURCES = gkmath.cpp\n",
"OBJS = gkmath.obj\n",
"OUTLIBS = gkmath.lib \n",
"OUTDLLS = gkmath.dll\n",
"\n",
"# 目标指令实现\n",
"$(OUTDLLS):$(SOURCES)\n",
"\t@cl /c $(CL_ARGS)/Fo:$(OBJS) gkmath.cpp\n",
"\t@link /MACHINE:X64 /nologo /DLL /OUT:gkmath.dll /IMPLIB:$(OUTLIBS) /EXPORT:gk_add $(OBJS)\n",
"\n",
"clean:\n",
"\tdel *.obj *.lib *.dll *.ilk *.exe *.exp 2>/Nul\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 动态库的调用方式1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 直接使用dll调用函数(lib不需要,只需要dll)【不推荐】"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 准备技术:\n",
" 1. HMODULE(指针) = LoadLibraryA(LPCSTR dllfilename):加载动态库到内存\n",
" 2. FARPROC(指针) = GetProcAddress(HMODULE hModule, LPCSTR functioname)\n",
" 3. 函数类型转换\n",
" 4. 调用\n",
" 5. 释放dll空间 :BOOL FreeLibrary(HMODULE)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 代码实现"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include <stdio.h>\n",
"#include <windows.h>\n",
"typedef int(*type_f)(int,int);\n",
"\n",
"int main(int argc, const char**argv){\n",
" // 加载dll模块\n",
" HMODULE h = LoadLibraryA(\"gkmath.dll\");\n",
" if(h == NULL){\n",
" printf(\"加载失败!\\n\");\n",
" return -1;\n",
" }\n",
" printf(\"加载成功!\");\n",
" // 查找函数\n",
" FARPROC f = GetProcAddress(h,\"gk_add\");\n",
" printf(\"%p\\n\",f);\n",
" //类型转换\n",
" type_f myfunc = (type_f)f;\n",
" //调用\n",
" printf(\"结果 :%d\\n\", myfunc(45,55));\n",
" //释放模块\n",
" FreeLibrary(h);\n",
"\n",
" \n",
"}\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 编译"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- /I:指定头文件路径"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 动态库的调用方式2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- 在编译的时候调用函数(不需要dll ,只需要lib, 但是运行时需要dll, 不需要lib)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include <stdio.h>\n",
"#include \"gkmath.h\"\n",
"#pragma comment(lib,\"gkmath.lib\") // 可加可不加 不推荐\n",
"int main(int argc, char*argv[]){\n",
" printf(\"调用结果:%d\\n\",gk_add(55,55));\n",
" return 0;\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Qt编译环境设置"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1.掌握的重点:\n",
" 1. GUI(Qt应用 + Qtwidgets(QDialog) )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2.Qt程序"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include <iostream>\n",
"\n",
"// Qt GUI模块:QtWidgets\n",
"// Qt 底层模块:QtCore\n",
"// Qt 图形的绘制模块QtGui\n",
"#include <Qtwidgets/QApplication>\n",
"#include <QtWidgets/QDialog>\n",
"\n",
"int main(int argc, char **argv){\n",
" // 1.构建一个Qt应用:QApplication\n",
" QApplication app(argc, argv);\n",
" // 2.窗体创建 QDialog\n",
" QDialog dlg;\n",
" // 窗体的属性(函数对getter/setter)\n",
" dlg.setWindowTitle(\"Qt开发\");\n",
" dlg.resize(640,480);\n",
" dlg.move(200,200);\n",
" dlg.show();\n",
" // 3.消息循环处理QApplication.exec()\n",
" int status = app.exec(); //block函数(消息循环)\n",
" // 4.退出程序,返回状态码给系统0-255 int 4字节 (-1=255)\n",
"\n",
" return status;\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3.Qt编译"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```bash\n",
"INCLUDES = /I \"D:\\Qt\\5.13.0\\msvc2017_64\\include\"\n",
"\n",
"LIBS = /LIBPATH:\"D:\\Qt\\5.13.0\\msvc2017_64\\lib\" \\\n",
" /DYNAMICBASE \\\n",
"\t\t \"Qt5Widgetsd.lib\" \\\n",
"\t\t \"Qt5Guid.lib\" \\\n",
"\t\t \"Qt5Cored.lib\"\n",
"CL_ARGS = /EHsc \\\n",
"\t\t /MDd \\\n",
"\t\t /source-charset:utf-8 \\\n",
"\t\t /execution-charset:utf-8 \\\n",
"\t\t /nologo\n",
"\n",
"LINK_ARGS = /MACHINE:X64 /NOLOGO \n",
"\n",
"main:qmain.cpp\n",
"\t@cl /c $(CL_ARGS) /Fo:main.obj $(INCLUDES) qmain.cpp \n",
"\t@link $(LINK_ARGS) $(LIBS) /OUT:main.exe main.obj\n",
"\n",
"clean:\n",
"\t@del *.exe *.obj *.exp 2>/Nul\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# DAY1 作业 : 写一个QT程序"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```C++\n",
"#include <iostream>\n",
"#include <Qtwidgets/QApplication>\n",
"#include <Qtwidgets/QDialog>\n",
"\n",
"int main(int argc, char **argv){\n",
" QApplication app(argc,argv);\n",
" QDialog dlg;\n",
" dlg.setWindowTitle(\"QT作业\");\n",
" dlg.resize(800,600);\n",
" dlg.move(200,500);\n",
" dlg.show();\n",
" int status = app.exec();\n",
" return status;\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"```bash\n",
"INCLUDES = /I \"D:\\Qt\\5.13.0\\msvc2017_64\\include\"\n",
"CL_FLAGS = /EHsc \\\n",
"\t\t /MD \\\n",
"\t\t /source-charset:utf-8 \\\n",
"\t\t /execution-charset:utf-8 \\\n",
"\t\t /nologo\n",
"LIBS = /LIBPATH:\"D:\\Qt\\5.13.0\\msvc2017_64\\lib\" \\\n",
"\t\t /DYNAMICBASE \\\n",
"\t\t \"Qt5widgets.lib\" \\\n",
"\t\t \"Qt5Gui.lib\" \\\n",
"\t\t \"Qt5Cored.lib\"\n",
"LINK_FLAGS = /MACHINE:X64 /nologo\n",
"\n",
"main: main.cpp\n",
"\t@cl /c $(CL_FLAGS) /Fo:main.obj $(INCLUDES) main.cpp\n",
"\t@link $(LINK_FLAGS) $(LIBS) /OUT:main.exe main.obj\n",
"clean:\n",
"\t@del *.exe *.obj *.exp 2>Nul\n",
"```"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.0"
}
},
"nbformat": 4,
"nbformat_minor": 4
}