最近在写实验的过程中,想可视化地观察实际结果是否与预期结果相似,就想使用matplotlib-cpp来实现,于是开启了踩坑之路(其实很简单,只是我弄了很久)。在此分享一下我的踩坑经验!
1. 问题总结
(1)找不到<Python.h>
(2)找不到Numpy
(3)重定义
(4)可以编译成功,执行时显示无法链接到动态库
(5)成功!!!
2. 解决思路
(1)首先,下载matplotlibcpp.h文件(https://github.com/lava/matplotlib-cpp),将其粘贴到工作区。并在相应的文件内引用该头文件。
#include "matplotlibcpp.h"
(2)开始编写CMakeLists.txt,完整的CMakeLists.txt如下所示:(值得注意的是,需要下载python、安装numpy和matplotlib包,不然也会报错)
cmake_minimum_required(VERSION 3.29) project(BM_Tree) set(CMAKE_CXX_STANDARD 20) find_package(Python3 COMPONENTS Interpreter Development REQUIRED) include_directories(${Python3_INCLUDE_DIRS}) # 更改为自己的文件 add_executable(BuildBM_Tree source/buildMTree.cpp include/MTREE/computeNNPairs.h include/MTREE/buildHuffmanTree.h include/MTREE/buildBMTree.h include/MTREE/matplotlibcpp.h) target_link_libraries(BuildBM_Tree ${Python3_LIBRARIES}) include_directories("更改为自己的Python路径/Python/Python313/Lib/site-packages/numpy/_core/include")
Following博主在Windows中,matplotlibcpp的使用-优快云博客的文章,非常简洁好用,强烈推荐!!!这个CMakeLists.txt可以解决上述1-(1)(2)(4)问题。
(3)针对重定义报错问题,只需注释掉matplotlibcpp.h文件中354、356行即可
static_assert(sizeof(long long) == 8); // template <> struct select_npy_type<long long> { const static NPY_TYPES type = NPY_INT64; }; static_assert(sizeof(unsigned long long) == 8); // template <> struct select_npy_type<unsigned long long> { const static NPY_TYPES type = NPY_UINT64; };
3. 踩坑历程
(1)一开始写了一个CMakeLists.txt,可以编译通过,但会显示1-(4)无法链接到动态库的问题,请教了博主"罗伯特祥",说是需要把编译的动态库拷贝到exe目录。
不过本人第二天重新执行的时候突然就执行成功了,就没有再去尝试这个方法,有类似问题的友友可以试一试。
cmake_minimum_required(VERSION 3.29) project(BM_Tree) set(CMAKE_CXX_STANDARD 20) # 找到 Python,改为自己的Python路径 set(PYTHONHOME C:/Users/Administrator/AppData/Local/Programs/Python/Python313) set(Python3_EXECUTABLE $PYTHONHOME}/python.exe) # 所需头文件路径 set(Python3_INCLUDE_DIRS ${PYTHONHOME}/include) # 所需库文件路径 set(Python3 LIBRARIES ${PYTHONHOME}/libs) # Numpy库文件路径 set(Python3_NUMPY_INCLUDE_DIRS ${PYTHONHOME}/Lib/site-packages/numpy/_core/include) # 主要用于查找并配置复杂的第三方软件包,这些软件包通常包含多个库和头文件,并且可能需要执行额外的配置步骤 find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy) add_executable(BuildBM_Tree source/buildMTree.cpp include/MTREE/computeNNPairs.h include/MTREE/buildHuffmanTree.h include/MTREE/buildBMTree.h include/MTREE/matplotlibcpp.h) target_link_libraries(BuildBM_Tree PUBLIC Python3::Python Python3::NumPy ${TORCH_LIBRARIES})
(2)后来我发现这个CMakeLists.txt有些画蛇添足,find_package()完全可以代替五个set()。。。
cmake_minimum_required(VERSION 3.29) project(BM_Tree) set(CMAKE_CXX_STANDARD 20) find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy) add_executable(BuildBM_Tree source/buildMTree.cpp include/MTREE/computeNNPairs.h include/MTREE/buildHuffmanTree.h include/MTREE/buildBMTree.h include/MTREE/matplotlibcpp.h) target_link_libraries(BuildBM_Tree PUBLIC Python3::Python Python3::NumPy ${TORCH_LIBRARIES})