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

嵌入式Python无法找到dist-packages依赖包问题求助

问题描述

在Ubuntu 22.04系统的C++ CMake项目中嵌入Python 3.10应用,已安装python-dev。相关配置与代码如下:

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)
project(MyPythonEmbeddedApp)

find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter Development)

add_executable(my_app src/main.cpp)
target_include_directories(my_app PRIVATE ${Python_INCLUDE_DIRS})
target_link_libraries(my_app Python3:python)

main.cpp

#include "Python.h"
#include <iostream>

int main(int argc, char** argv)
{
    Py_Initialize();

    // ./ is the path to myPythonModule.py
    // Must add /usr/lib/python3.10 or can't find any base python modules in script
    // Adding location to dist-packages makes valkka-onvif found
    PySys_SetPath(L"./:/usr/lib/python3.10:/usr/local/lib/python3.10/dist-packages/");

    PyObject* pythonModule = PyImport_ImportModule("myPythonModule");
    Py_DECREF(pythonModule);
    Py_Finalize();
    return 0;
}

myPythonModule.py

from valkka.onvif import OnVif, DeviceIO, DeviceManagement, getWSDLPath

class OnvifClass(OnVif):
    serial_port = []

    def __init__(self, ip="172.25.0.100", port=8000, user="", password=""):
        self.ip = ip
        self.port = port
        print("Initialized Handler")

运行时出现错误:FATAL: you are importing valkka.onvif, but don't have zeep installed. Please install zeep with pip install zeep,该提示来自/usr/local/lib/python3.10/dist-packages/valkka/onvif/base.py对zeep的导入。

已通过sudo pip3 install valkka-onvif安装包到/usr/local目录,同时安装了指定版本zeep==4.0.0,两个包均位于/usr/local/lib/python3.10/dist-packages/。命令行运行该Python模块无问题,但嵌入式运行时依赖找不到。

解决方案

1. 修复PySys_SetPath的使用方式

直接调用PySys_SetPath会完全覆盖Python默认的sys.path,导致部分依赖包的路径丢失。正确做法是在原有路径基础上追加自定义路径:

修改main.cpp中的路径设置部分:

Py_Initialize();

// 获取原有sys.path
PyObject* sysPath = PySys_GetObject((char*)"path");
// 追加自定义路径
PyList_Append(sysPath, PyUnicode_FromString("./"));
PyList_Append(sysPath, PyUnicode_FromString("/usr/local/lib/python3.10/dist-packages/"));

// 原有的/usr/lib/python3.10通常已经在默认path中,无需重复添加

2. 修正CMake配置中的变量错误

  • 变量名Python_INCLUDE_DIRS应为Python3_INCLUDE_DIRS(对应find_package(Python3 ...))
  • 链接库的写法应为Python3::Python(双冒号是CMake标准的目标链接语法)

修正后的CMakeLists.txt:

cmake_minimum_required(VERSION 3.21)
project(MyPythonEmbeddedApp)

find_package(Python3 3.10 REQUIRED COMPONENTS Interpreter Development)

add_executable(my_app src/main.cpp)
target_include_directories(my_app PRIVATE ${Python3_INCLUDE_DIRS})
target_link_libraries(my_app Python3::Python)

3. 验证嵌入式Python环境与命令行一致性

在main.cpp中添加代码,打印当前Python的可执行路径和sys.path,确认与命令行python3的环境一致:

// 在Py_Initialize()后添加
PyObject* sysModule = PyImport_ImportModule("sys");
PyObject* executable = PyObject_GetAttrString(sysModule, "executable");
PyObject* path = PyObject_GetAttrString(sysModule, "path");

// 打印executable
const char* execStr = PyUnicode_AsUTF8(executable);
std::cout << "Python executable: " << execStr << std::endl;

// 打印sys.path
Py_ssize_t pathLen = PyList_Size(path);
std::cout << "sys.path:" << std::endl;
for (Py_ssize_t i = 0; i < pathLen; ++i) {
    PyObject* item = PyList_GetItem(path, i);
    const char* itemStr = PyUnicode_AsUTF8(item);
    std::cout << "  " << itemStr << std::endl;
}

Py_DECREF(sysModule);
Py_DECREF(executable);
Py_DECREF(path);

运行程序后对比命令行python3 -c "import sys; print(sys.executable); print(sys.path)"的输出,确保路径一致。

4. 确认zeep包的安装路径

如果zeep安装在其他路径(比如用户目录~/.local/lib/python3.10/site-packages/),需要将该路径也追加到sys.path中。可以通过命令查看安装位置:

pip3 show zeep

输出中的Location字段即为zeep的安装路径,将其添加到main.cpp的sys.path追加列表中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:29:55