You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows下CMake构建含.cxx/.py/依赖DLL项目的EXE打包及Py转DLL方法

针对你的需求,我整理了几个可行的方案,都是在Windows+CMake环境下适配Qt/PyQt/VTK/ITK这类依赖的,能帮你把Python脚本转换成DLL来保护源码:

方案1:用Cython将Python脚本编译为C扩展DLL

Cython可以把Python代码转成C/C++代码,再编译成DLL,既能保护源码,又能和你的CMake项目无缝集成。

步骤:

  1. 安装Cython
    先通过pip安装:

    pip install cython
    
  2. 将Python脚本转为.pyx文件
    把你要保护的Python脚本(比如my_script.py)重命名为my_script.pyx,如果需要调用C库(比如Qt/VTK/ITK的C接口),还可以在.pyx里添加Cython的类型声明来提升性能。

  3. 在CMake中集成Cython编译
    在你的CMakeLists.txt里添加以下配置,用来调用Cython生成C++代码,再编译成DLL:

    # 找到Python开发环境
    find_package(Python3 REQUIRED COMPONENTS Development)
    find_package(Cython REQUIRED)
    
    # 定义要编译的pyx文件
    set(PYX_FILES my_script.pyx)
    
    # 用Cython生成C++代码
    foreach(pyx_file ${PYX_FILES})
        get_filename_component(pyx_name ${pyx_file} NAME_WE)
        add_custom_command(
            OUTPUT ${pyx_name}.cxx
            COMMAND ${Python3_EXECUTABLE} -m cython ${pyx_file} --cplus -o ${pyx_name}.cxx
            DEPENDS ${pyx_file}
            COMMENT "Compiling ${pyx_file} to ${pyx_name}.cxx"
        )
    endforeach()
    
    # 编译生成DLL
    add_library(my_python_dll SHARED ${pyx_name}.cxx)
    target_link_libraries(my_python_dll PRIVATE
        Python3::Python
        # 添加你的Qt/VTK/ITK依赖库,比如:
        Qt5::Core
        VTK::CommonCore
        ITK::Common
    )
    
    # 设置DLL输出路径,和主程序一致
    set_target_properties(my_python_dll PROPERTIES
        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    )
    
  4. 在主程序中调用DLL
    编译完成后,你可以在原来的C++/Python主程序中通过Python的C API或者直接导入这个DLL(如果是Python调用的话)来执行原来的逻辑,不再需要暴露原始.py文件。

方案2:将Python字节码嵌入C++ DLL

这个方案是把Python脚本编译成字节码(.pyc),再嵌入到C++代码中编译成DLL,完全避免脚本文件暴露。

步骤:

  1. 生成Python字节码
    打开命令行,运行以下命令生成.pyc文件:

    python -m py_compile my_script.py
    

    生成的字节码会在__pycache__目录下,比如my_script.cpython-310.pyc(后缀和Python版本相关)。

  2. 将字节码转为C数组
    用xxd工具(Windows下可以通过Git Bash或者MinGW安装)把.pyc文件转成C头文件:

    xxd -i my_script.cpython-310.pyc > script_bytecode.h
    

    这个头文件里会生成一个unsigned char数组,包含字节码的二进制数据。

  3. 编写C++代码加载字节码
    创建一个python_embed.cpp文件,用Python C API加载内存中的字节码:

    #include <Python.h>
    #include "script_bytecode.h"
    
    extern "C" __declspec(dllexport) void run_my_script() {
        // 初始化Python环境
        Py_Initialize();
    
        // 从内存加载字节码
        PyObject* code_obj = PyMarshal_ReadObjectFromString(
            (const char*)my_script_cpython_310_pyc,
            my_script_cpython_310_pyc_len
        );
        if (!code_obj) {
            PyErr_Print();
            return;
        }
    
        // 执行字节码
        PyObject* module = PyImport_ExecCodeModule("my_script", code_obj);
        if (!module) {
            PyErr_Print();
            Py_DECREF(code_obj);
            return;
        }
    
        // 清理资源
        Py_DECREF(module);
        Py_DECREF(code_obj);
        Py_Finalize();
    }
    
  4. CMake编译为DLL
    在CMakeLists.txt中添加配置:

    find_package(Python3 REQUIRED COMPONENTS Development)
    add_library(embedded_python_dll SHARED python_embed.cpp)
    target_link_libraries(embedded_python_dll PRIVATE
        Python3::Python
        # 添加Qt/VTK/ITK依赖
        Qt5::Core
        VTK::CommonCore
        ITK::Common
    )
    set_target_properties(embedded_python_dll PROPERTIES
        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
    )
    
  5. 主程序调用
    主程序通过LoadLibrary或者直接链接DLL,调用run_my_script函数即可执行原来的Python逻辑。

方案3:用Nuitka编译Python为C++ DLL

Nuitka是一个Python到C++的编译器,可以直接把Python脚本编译成独立的DLL,自动处理依赖。

步骤:

  1. 安装Nuitka

    pip install nuitka
    
  2. 编译Python脚本为DLL
    运行以下命令,把脚本编译成DLL,同时打包依赖的库:

    nuitka --module --standalone --include-package=PyQt5 --include-package=vtk --include-package=itk my_script.py
    
    • --module:生成DLL而不是EXE
    • --standalone:打包所有依赖
    • --include-package:指定需要包含的依赖包(根据你的实际依赖调整)
  3. 集成到CMake项目
    把Nuitka生成的DLL(比如my_script.pyd,Windows下pyd就是DLL)复制到你的项目输出目录,然后在CMake中链接这个DLL:

    add_executable(your_main_app main.cxx)
    target_link_libraries(your_main_app PRIVATE
        ${CMAKE_BINARY_DIR}/bin/my_script.pyd
        # 其他依赖库
    )
    

注意事项

  • 无论用哪个方案,都要确保Python版本一致:编译DLL用的Python版本必须和主程序使用的Python版本完全匹配,否则会出现兼容性错误。
  • 分发时要包含所有依赖的DLL:Qt、VTK、ITK以及Python的运行时DLL(比如python310.dll)都需要和你的主程序、生成的DLL一起打包。
  • 测试时要在干净的Windows环境下验证:避免依赖开发环境中的库,确保分发包可以独立运行。

内容的提问来源于stack exchange,提问作者Dwij Mistry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:06:50