From 656a6cb2a63858caa6e9dd8cf1b8c3f8269b63f1 Mon Sep 17 00:00:00 2001 From: DragonAura Date: Mon, 8 May 2023 18:51:07 +0800 Subject: [PATCH 1/9] fix: :bug: fix python compile fail --- dependency/shell/compile.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dependency/shell/compile.sh b/dependency/shell/compile.sh index 0ee08b8..fd83cba 100644 --- a/dependency/shell/compile.sh +++ b/dependency/shell/compile.sh @@ -16,12 +16,13 @@ do elif [ -f "${bind}/player${i}.py" ]; then pushd ../python cp -f $bind/player$i.py ./PyAPI/AI.py - python3 -m compileall ./PyAPI + python3 -m compileall ./PyAPI >compile_log$i.txt 2>&1 if [ ! -f ./PyAPI/__pycache__/AI.cpython-39.pyc ]; then flag=0 else rm -rf ./PyAPI/__pycache__/AI.cpython-39.pyc fi + mv ./compile_log$i.txt $bind/compile_log$i.txt popd fi let "i++" From 8faa06a811bfb39b38f3fb169df7bdb3da5c19d1 Mon Sep 17 00:00:00 2001 From: DragonAura Date: Mon, 8 May 2023 19:25:36 +0800 Subject: [PATCH 2/9] fix: :poop: fix python compile --- dependency/Dockerfile/Dockerfile_cpp | 2 ++ dependency/shell/py_output.sh | 8 ++++++++ 2 files changed, 10 insertions(+) create mode 100644 dependency/shell/py_output.sh diff --git a/dependency/Dockerfile/Dockerfile_cpp b/dependency/Dockerfile/Dockerfile_cpp index 90a5846..2042924 100644 --- a/dependency/Dockerfile/Dockerfile_cpp +++ b/dependency/Dockerfile/Dockerfile_cpp @@ -4,10 +4,12 @@ MAINTAINER eesast WORKDIR /usr/local COPY ./CAPI/cpp /usr/local/PlayerCode/CAPI/cpp +COPY ./CAPI/python /usr/local/PlayerCode/CAPI/python COPY ./dependency/proto /usr/local/PlayerCode/dependency/proto COPY ./dependency/shell /usr/local/PlayerCode/dependency/shell WORKDIR /usr/local/PlayerCode/dependency/proto RUN bash ../shell/cpp_output.sh +RUN bash ../shell/py_output.sh WORKDIR /usr/local/PlayerCode/CAPI/cpp COPY ./dependency/shell/compile.sh . ENTRYPOINT ["bash","./compile.sh"] diff --git a/dependency/shell/py_output.sh b/dependency/shell/py_output.sh new file mode 100644 index 0000000..e1b08b6 --- /dev/null +++ b/dependency/shell/py_output.sh @@ -0,0 +1,8 @@ +python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. MessageType.proto +python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. Message2Clients.proto +python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. Message2Server.proto +python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. --grpc_python_out=. Services.proto +chmod -R 755 ./ +mkdir -p ../../CAPI/python/proto +mv -f ./*.py ../../CAPI/python/proto +mv -f ./*.pyi ../../CAPI/python/proto From 559aa1a62777e7daaf5da8118a855e6f27953f0b Mon Sep 17 00:00:00 2001 From: DragonAura Date: Mon, 8 May 2023 19:31:52 +0800 Subject: [PATCH 3/9] fix: :poop: remove py_output --- dependency/Dockerfile/Dockerfile_cpp | 1 - dependency/shell/py_output.sh | 8 -------- 2 files changed, 9 deletions(-) delete mode 100644 dependency/shell/py_output.sh diff --git a/dependency/Dockerfile/Dockerfile_cpp b/dependency/Dockerfile/Dockerfile_cpp index 2042924..a81a14a 100644 --- a/dependency/Dockerfile/Dockerfile_cpp +++ b/dependency/Dockerfile/Dockerfile_cpp @@ -9,7 +9,6 @@ COPY ./dependency/proto /usr/local/PlayerCode/dependency/proto COPY ./dependency/shell /usr/local/PlayerCode/dependency/shell WORKDIR /usr/local/PlayerCode/dependency/proto RUN bash ../shell/cpp_output.sh -RUN bash ../shell/py_output.sh WORKDIR /usr/local/PlayerCode/CAPI/cpp COPY ./dependency/shell/compile.sh . ENTRYPOINT ["bash","./compile.sh"] diff --git a/dependency/shell/py_output.sh b/dependency/shell/py_output.sh deleted file mode 100644 index e1b08b6..0000000 --- a/dependency/shell/py_output.sh +++ /dev/null @@ -1,8 +0,0 @@ -python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. MessageType.proto -python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. Message2Clients.proto -python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. Message2Server.proto -python3 -m grpc_tools.protoc -I. --python_out=. --pyi_out=. --grpc_python_out=. Services.proto -chmod -R 755 ./ -mkdir -p ../../CAPI/python/proto -mv -f ./*.py ../../CAPI/python/proto -mv -f ./*.pyi ../../CAPI/python/proto From 0fd066a4e27e0b6b5722329bc1d3e2025a86e178 Mon Sep 17 00:00:00 2001 From: DragonAura Date: Mon, 8 May 2023 19:37:19 +0800 Subject: [PATCH 4/9] fix: :poop: edit run.sh --- dependency/shell/run.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/dependency/shell/run.sh b/dependency/shell/run.sh index 9046d3e..82b9833 100644 --- a/dependency/shell/run.sh +++ b/dependency/shell/run.sh @@ -53,6 +53,10 @@ if [ -f $playback_dir/start.lock ]; then sleep 1 ps -p $server_pid > /dev/null 2>&1 done + result=$(cat /usr/local/playback/result.json) + score0=$(echo "$result" | grep -oP '(?<="Student":)\d+') + score1=$(echo "$result" | grep -oP '(?<="Tricker":)\d+') + curl $URL -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"result":[{"team_id":0, "score":'${score0}'}, {"team_id":1, "score":'${score1}'}], "mode":'${MODE}'}'> $playback_dir/send.log 2>&1 touch $playback_dir/finish.lock echo "Finish" else @@ -62,8 +66,3 @@ else mv -f temp.lock $playback_dir/video.thuaipb kill -9 $server_pid fi - -result=$(cat /usr/local/playback/result.json) -score0=$(echo "$result" | grep -oP '(?<="Student":)\d+') -score1=$(echo "$result" | grep -oP '(?<="Tricker":)\d+') -curl $URL -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"result":[{"team_id":0, "score":'${score0}'}, {"team_id":1, "score":'${score1}'}], "mode":'${MODE}'}' From 67d1dc40ca1a5fd40620fc6984d7333c13a083fe Mon Sep 17 00:00:00 2001 From: Changli Tang <84725343+TCL606@users.noreply.github.com> Date: Mon, 8 May 2023 21:47:24 +0800 Subject: [PATCH 5/9] Update run.sh --- dependency/shell/run.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/dependency/shell/run.sh b/dependency/shell/run.sh index 82b9833..6585173 100644 --- a/dependency/shell/run.sh +++ b/dependency/shell/run.sh @@ -56,6 +56,7 @@ if [ -f $playback_dir/start.lock ]; then result=$(cat /usr/local/playback/result.json) score0=$(echo "$result" | grep -oP '(?<="Student":)\d+') score1=$(echo "$result" | grep -oP '(?<="Tricker":)\d+') + touch $playback_dir/send.flag curl $URL -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"result":[{"team_id":0, "score":'${score0}'}, {"team_id":1, "score":'${score1}'}], "mode":'${MODE}'}'> $playback_dir/send.log 2>&1 touch $playback_dir/finish.lock echo "Finish" From 4ef8e824f77e20aa49bd501edc8e305d7e13270c Mon Sep 17 00:00:00 2001 From: Changli Tang <84725343+TCL606@users.noreply.github.com> Date: Mon, 8 May 2023 22:06:11 +0800 Subject: [PATCH 6/9] Update run.sh --- dependency/shell/run.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dependency/shell/run.sh b/dependency/shell/run.sh index 6585173..69fd6ae 100644 --- a/dependency/shell/run.sh +++ b/dependency/shell/run.sh @@ -53,10 +53,13 @@ if [ -f $playback_dir/start.lock ]; then sleep 1 ps -p $server_pid > /dev/null 2>&1 done + touch $playback_dir/1.flag result=$(cat /usr/local/playback/result.json) + touch $playback_dir/2.flag score0=$(echo "$result" | grep -oP '(?<="Student":)\d+') + touch $playback_dir/3.flag score1=$(echo "$result" | grep -oP '(?<="Tricker":)\d+') - touch $playback_dir/send.flag + touch $playback_dir/4.flag curl $URL -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" -d '{"result":[{"team_id":0, "score":'${score0}'}, {"team_id":1, "score":'${score1}'}], "mode":'${MODE}'}'> $playback_dir/send.log 2>&1 touch $playback_dir/finish.lock echo "Finish" From 298ee581a2d5ecf8c116d762043e52ee2ba06265 Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Mon, 8 May 2023 22:12:25 +0800 Subject: [PATCH 7/9] docs: :memo: add capi c++ config tutorial --- CAPI/cpp/README.md | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/CAPI/cpp/README.md b/CAPI/cpp/README.md index 20e7dd1..c8e33ee 100644 --- a/CAPI/cpp/README.md +++ b/CAPI/cpp/README.md @@ -52,6 +52,55 @@ C++ 通信组件与选手接口 - 避免忙等待,注意线程安全,做好线程同步 - 善于使用 [Google](https://www.google.com/) 并使用[**英文**](https://en.wikipedia.org/wiki/American_English)搜索,善于查阅 [Microsoft Learn](https://learn.microsoft.com/)、[cppreference](https://en.cppreference.com/)、[StackOverflow](https://stackoverflow.com/) 以及第三方库官方文档等;不应轻信 [CSDN](https://www.csdn.net/) 等劣质博客社区以及[博客园](https://www.cnblogs.com/)、[简书](https://www.jianshu.com/)等质量参差不齐的博客社区,对其内容需全方位多角度仔细求证方可相信 +## 开发纪实 + +### C++ SDK Windows 环境配置 + +#### 配置方法 + +起初 C++ 开发时使用 Linux 开发,但在选手包发布 Windows SDK 时遇到诸多问题。Windows 平台的 C++ 接口使用 Visual Studio 进行环境配置。期间遇到诸多问题,配置环境方法如下: + +1. 更新 Visual Studio:由于届时要求选手与开发组使用**完全相同**版本的 Visual Studio,否则可能会出现找不到一些标准库内置的符号的问题,因此在选手包发布前夕,将开发组的 Visual Studio 升级到最新版后执行步骤 2 +2. 编译 gRPC:分别编译 Debug 和 Release 的 gRPC 依赖库各一份。方法有二: + - 方法一:根据 [gRPC Windows 生成教程](https://github.com/grpc/grpc/blob/0b2609a61d50f2dbba4604978ef9243543a2675a/BUILDING.md#windows-using-visual-studio-2019-or-later) 在本地分别编译一份 `Debug` 和 `Release`(即在 CMake config 参数中分别指定 Debug 和 Release 各生成一份 Visual Studio 工程)的 x64 平台的依赖库。注意使用静态编译,根据[此原则](https://github.com/grpc/grpc/blob/0b2609a61d50f2dbba4604978ef9243543a2675a/BUILDING.md#windows-a-note-on-building-shared-libs-dlls)**不生成** gRPC 和 Protocol Buffers 本身的 DLL,即只有 `.lib` 无 `.dll`(但是可能会有一些其依赖的第三方库的 `.dll`),将 Debug 和 Release 生成的 `.lib` 和 `.dll`(如果有的话)均分别保存 + - 方法二:根据 [gRPC vcpkg 安装教程](https://github.com/grpc/grpc/tree/master/src/cpp#install-using-vcpkg-package) 安装 **`x64-windows-static`** 的 gRPC,即执行 `vcpkg install grpc:x64-windows-static`,以生成静态库(注意 vcpkg 需要调用本地的 Visual Studio 进行现场编译和生成,所以所耗时间可能较长,请耐心等待;并且此步骤由于需要从 GitHub 上现场拉源代码,因此可能需要科学上网)。然后进入 vcpkg 的安装目录,将里面安装的 gRPC 的所有 Debug 和 Release 的 `.lib` 和 `.dll`(如果有的话)分别保存一份 +3. 提取 gRPC 头文件:参考 [gRPC 所有所需头文件](https://github.com/eesast/THUAI6/tree/217d87aeedf6735e3257acb1e2c70574df45b823/CAPI/cpp/grpc)将头文件放入本仓库的相应目录内,以供使用(记得放该版本对应的 LICENSE x)。 +4. 配置 `.vcxproj` 和 `.vcxproj.filters`:`.vcxproj` 用于配置项目的编译与链接,`.vcxproj.filters` 用于配置 Vsiual Studio 的筛选器的结构(即解决方案资源管理器的结构)。参考 THUAI6 的 [`API.vcxproj`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj) 和 [`API.vcxproj.filters`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj.filters)。基本上可以直接无脑复制过来,不用做什么修改。如果非要在 Visual Studio 里手动配置,需要配置以下几项(以下的链接均以 X64 Release 为例,Debug 的相应配置在相应链接的上面一些的位置): + - 添加头文件和源文件:[将**自己编写**的 `.h` 和 `.cpp` 文件加入到项目中](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L169-L197)(包括 protoc 生成的那些 `.pb.h` 和 `.pb.cc`,但这些最好参照 `API.vcxproj.filters` 的组织结构[各单独开一个子筛选器](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj.filters#L16-L21)放进去以使得 Visual Studio 打开时更美观) + - 在项目属性中的 Debug 和 Release 的“C/C++”的“语言”中[均设置 C++ 语言标准为 `/std:c++17`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L154)、[C 语言标准为 `/std:c17`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L155) + - 在项目属性中的 Debug 和 Release 的[附加编译选项(即在“C/C++”的“命令行”)里均增加 `/source-charset:utf-8` 选项](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L157),以保证编译时编译器使用 UTF-8 编码进行源文件读取(注意这个与 Visual Studio 的高级保存选项不同,高级保存选项决定了文件的保存时的保存编码,而非编译器编译时读取使用的编码) + - 设置头文件的搜索路径:在项目属性的“C/C++”的首页的“附加包含目录”中设置 Debug 和 Release 下的[搜索头文件的根路径](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L156),注意 Windows 下的路径分隔符最好使用 `\` 而非 `/`,负责可能会出现一些玄学问题 + - 设置生成方式为静态生成:在项目属性的“C/C++”的“代码生成”的“运行库”中,[Debug 下设置其为“多线程调试(`/MTd`)”](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L137),[Release 下设置其为“多线程(`/MT`)”](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L158) + - 将之前提取的 Debug 和 Release 的 `.lib` 分别放在项目中的单独的文件夹里(THUAI6 使用的是 `CAPI\cpp\lib\debug` 和 `CAPI\cpp\lib\release`),并[使用 `.gitignore` 忽略掉](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/.gitignore#L502) + - 在项目属性的“链接器”的首页的“附加库目录”中分别配置 Debug 和 Release 的 [`.lib` 文件的相应路径](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L166) + - 在项目属性中的“链接器”的“输入”的“附加依赖库”中分别配置 Debug 和 Release [所需要链接的库的文件名](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L165)。注意 Debug 和 Release 链接的库可能并不完全相同,建议在 cmd 中使用 `dir /b` 将其自动列举并复制。还需要注意需要手动指定链接一些 Windows 自带的 `lib`,例如 `Ws2_32.lib`、`Crypt32.lib`、`Iphlpapi.lib` 等。如果生成过程中不通过,表示找不到一些函数,则在 Google 中搜索该函数,如果发现是 Windows 系统的 API 函数则会搜到[微软官方文档](https://learn.microsoft.com) 的对应链接的页面,则在页面最下方会表明它所在的 `.lib`(例如 [`CreateProcessA` 的页面](https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa#requirements)),加进去即可 + - 然后进行生成解决方案。如果感觉编译的速度过慢,可以在项目属性的 `C/C++` 的“所有选项”中搜索并行编译,并开启之(`/Qpar`)。不过由于 THUAI6 的疏忽,忘记开启了并行编译 + - 然后开始运行。如果提示缺少一些 DLL,可以把之前保存的 `.dll` 文件(如果有的话)放在与 `.exe` 相同的目录下。该目录为**与 `.sln` 相同目录的**(不是与 `.vcxproj` 相同目录的)`x64\Debug` 和 `x64\Release` + - 如果 x64 的 Debug 和 x64 的 Release 均生成成功,那么找一台没配过的电脑再试一次 + - 随便写点 AI 代码,重新生成解决方案,确认成功后发布选手包 + - 有兴趣也可以支持一下 x86 的 Windows(x + - 有兴趣还可以支持一下 Cygwin(x + +### Q&A + +#### 为什么不用 CMake + +1. 由于 CMake 生成的 Visual Studio 工程是绝对路径,因此不能将 CMake 生成的 Visual Studio 工程直接给选手,需要选手使用 CMake,增加了选手尤其是大一小白选手的负担 +2. 对 Debug 和 Release 分别编译时,需要 CMake 分别生成 Debug 和 Release 的 Visual Studio 工程,而难以使用 Visual Studio 和 MSBuild 自带的 Debug 和 Release 的切换方式,这就需要生成两份 Visual Studio 工程,对选手的测试来说也是一种麻烦 + +#### 为什么不让选手用 vcpkg + +1. vcpkg 是将代码拉下来本地编译。拉代码过程需要科学上网,这对一些大一小白选手来说是个不小的负担 +2. vcpkg 编译过程极其漫长,会极大消磨选手的耐心 + +#### 为什么不用 CLion 配合 MinGW、MinGW-w64 等 + +1. 贵校程设课大多数使用 Visual Studio。对大多数选手来说,这是最易上手的 +2. 开箱即用,方便 +3. MinGW 已停止维护,正在维护的是 MinGW-w64,两者名称很像,选手尤其是使用百度等劣质搜索引擎或查阅 CSDN 等劣质博客安装时极易混淆 +4. MinGW 需要附加更多的其自己的依赖库如 glibc 等,此 glibc 依然依赖 msvcrt,多一层依赖库便增加了一些版本不兼容问题的风险 +5. 其与 MSVC 的 Name Mangling 的规则、ABI 等并不一致或不完全一致,增加各种不兼容问题的风险 + ## 开发人员 - ......(自己加) From 765d1a80d6532a7c2016be8b30032dee42a8b81c Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Mon, 8 May 2023 22:14:01 +0800 Subject: [PATCH 8/9] docs: :memo: update capi c++ config tutorial --- CAPI/cpp/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CAPI/cpp/README.md b/CAPI/cpp/README.md index c8e33ee..70b67ab 100644 --- a/CAPI/cpp/README.md +++ b/CAPI/cpp/README.md @@ -97,9 +97,10 @@ C++ 通信组件与选手接口 1. 贵校程设课大多数使用 Visual Studio。对大多数选手来说,这是最易上手的 2. 开箱即用,方便 -3. MinGW 已停止维护,正在维护的是 MinGW-w64,两者名称很像,选手尤其是使用百度等劣质搜索引擎或查阅 CSDN 等劣质博客安装时极易混淆 -4. MinGW 需要附加更多的其自己的依赖库如 glibc 等,此 glibc 依然依赖 msvcrt,多一层依赖库便增加了一些版本不兼容问题的风险 -5. 其与 MSVC 的 Name Mangling 的规则、ABI 等并不一致或不完全一致,增加各种不兼容问题的风险 +3. Visual Studio 已使用多年,坑全部踩过了一遍,突然变更又要重新踩坑 +4. MinGW 已停止维护,正在维护的是 MinGW-w64,两者名称很像,选手尤其是使用百度等劣质搜索引擎或查阅 CSDN 等劣质博客安装时极易混淆 +5. MinGW 需要附加更多的其自己的依赖库如 glibc 等,此 glibc 依然依赖 msvcrt,多一层依赖库便增加了一些版本不兼容问题的风险 +6. 其与 MSVC 的 Name Mangling 的规则、ABI 等并不一致或不完全一致,增加各种不兼容问题的风险 ## 开发人员 From 57f25cbbde1ef216a2ad61e8d318d2e4764730a1 Mon Sep 17 00:00:00 2001 From: Timothy Liu Date: Mon, 8 May 2023 22:15:36 +0800 Subject: [PATCH 9/9] docs :memo: update capi c++ config tutorial --- CAPI/cpp/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CAPI/cpp/README.md b/CAPI/cpp/README.md index 70b67ab..21daeeb 100644 --- a/CAPI/cpp/README.md +++ b/CAPI/cpp/README.md @@ -65,7 +65,7 @@ C++ 通信组件与选手接口 - 方法一:根据 [gRPC Windows 生成教程](https://github.com/grpc/grpc/blob/0b2609a61d50f2dbba4604978ef9243543a2675a/BUILDING.md#windows-using-visual-studio-2019-or-later) 在本地分别编译一份 `Debug` 和 `Release`(即在 CMake config 参数中分别指定 Debug 和 Release 各生成一份 Visual Studio 工程)的 x64 平台的依赖库。注意使用静态编译,根据[此原则](https://github.com/grpc/grpc/blob/0b2609a61d50f2dbba4604978ef9243543a2675a/BUILDING.md#windows-a-note-on-building-shared-libs-dlls)**不生成** gRPC 和 Protocol Buffers 本身的 DLL,即只有 `.lib` 无 `.dll`(但是可能会有一些其依赖的第三方库的 `.dll`),将 Debug 和 Release 生成的 `.lib` 和 `.dll`(如果有的话)均分别保存 - 方法二:根据 [gRPC vcpkg 安装教程](https://github.com/grpc/grpc/tree/master/src/cpp#install-using-vcpkg-package) 安装 **`x64-windows-static`** 的 gRPC,即执行 `vcpkg install grpc:x64-windows-static`,以生成静态库(注意 vcpkg 需要调用本地的 Visual Studio 进行现场编译和生成,所以所耗时间可能较长,请耐心等待;并且此步骤由于需要从 GitHub 上现场拉源代码,因此可能需要科学上网)。然后进入 vcpkg 的安装目录,将里面安装的 gRPC 的所有 Debug 和 Release 的 `.lib` 和 `.dll`(如果有的话)分别保存一份 3. 提取 gRPC 头文件:参考 [gRPC 所有所需头文件](https://github.com/eesast/THUAI6/tree/217d87aeedf6735e3257acb1e2c70574df45b823/CAPI/cpp/grpc)将头文件放入本仓库的相应目录内,以供使用(记得放该版本对应的 LICENSE x)。 -4. 配置 `.vcxproj` 和 `.vcxproj.filters`:`.vcxproj` 用于配置项目的编译与链接,`.vcxproj.filters` 用于配置 Vsiual Studio 的筛选器的结构(即解决方案资源管理器的结构)。参考 THUAI6 的 [`API.vcxproj`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj) 和 [`API.vcxproj.filters`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj.filters)。基本上可以直接无脑复制过来,不用做什么修改。如果非要在 Visual Studio 里手动配置,需要配置以下几项(以下的链接均以 X64 Release 为例,Debug 的相应配置在相应链接的上面一些的位置): +4. 配置 `.vcxproj` 和 `.vcxproj.filters`:`.vcxproj` 用于配置项目的编译与链接,`.vcxproj.filters` 用于配置 Visual Studio 的筛选器的结构(即解决方案资源管理器的结构)。参考 THUAI6 的 [`API.vcxproj`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj) 和 [`API.vcxproj.filters`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj.filters)。基本上可以直接无脑复制过来,不用做什么修改。如果非要在 Visual Studio 里手动配置,需要配置以下几项(以下的链接均以 x64 Release 为例,Debug 的相应配置在相应链接的上面一些的位置): - 添加头文件和源文件:[将**自己编写**的 `.h` 和 `.cpp` 文件加入到项目中](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L169-L197)(包括 protoc 生成的那些 `.pb.h` 和 `.pb.cc`,但这些最好参照 `API.vcxproj.filters` 的组织结构[各单独开一个子筛选器](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj.filters#L16-L21)放进去以使得 Visual Studio 打开时更美观) - 在项目属性中的 Debug 和 Release 的“C/C++”的“语言”中[均设置 C++ 语言标准为 `/std:c++17`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L154)、[C 语言标准为 `/std:c17`](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L155) - 在项目属性中的 Debug 和 Release 的[附加编译选项(即在“C/C++”的“命令行”)里均增加 `/source-charset:utf-8` 选项](https://github.com/eesast/THUAI6/blob/c8e1fbe299c67a6e101fa02e85bcc971acd0f48b/CAPI/cpp/API/API.vcxproj#L157),以保证编译时编译器使用 UTF-8 编码进行源文件读取(注意这个与 Visual Studio 的高级保存选项不同,高级保存选项决定了文件的保存时的保存编码,而非编译器编译时读取使用的编码)