软件编程实践笔记(一)

{

"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

}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容