解决C++调用python传递中文路径的问题

3 篇文章 0 订阅

背景:最近在做使用C++调用python代码来进行图像处理,需要传入一个图像文件的路径,使用

char *picPath = "E:\\pic.jpg";
PyObject *path_ = Py_BuildValue("s", picPath);

来生成图像路径的python对象,当路径是全英文时没有问题,当路径包含中文时,无法创建PyObject对象,path_为空。

原因:

python默认使用utf-8编码,因此当字符串含有中文时,需要转换成utf-8编码的字符串。

解决办法:

1,将路径转成utf-8编码的字符串。由于界面用qt实现,因此我使用了qt的函数来转换:

std::string picPath = "E:\\图片\\pic.jpg";
char *picpath = QString::fromLocal8Bit(picPath.c_str()).toUtf8().data();
PyObject *path_ = Py_BuildValue("s", picPath);

由于在vs环境中,是不支持utf-8的显示的,因此转换后的picpath是乱码。

附上从python接受字符串的转换:

char *retStr = new char[256];
PyArg_Parse(pReturn, "s", &retStr);
QString ss = QString::fromUtf8(retStr);
std::string ss2 = std::string(ss.toLocal8Bit());
delete retStr;

2,将路径转为宽字符,再调用PyUnicode_FromUnicode 来生成PyObject:

std::string picPath = "E:\\图片\\pic.jpg";
QString ss = QString::fromLocal8Bit(picPath.c_str());
wchar_t *picpath_ = new wchar_t[length() + 1];
int wclen = ss.toWCharArray(picpath_);
picpath_[wclen] = 0;

PyObject *path_ = PyUnicode_FromUnicode(picpath_, wclen);

delete picpath_;

3,将路径使用base64编码后传给python,在python里经base64解码后恢复路径(此方法未尝试)。

这时能生成path_对象,但是调用python接口时返回失败,经排查,是由于python代码里使用了cv2.imread()来读入图像,而该接口对中文路径无效;网上搜索了一下,找到一个解决办法:

import numpy as np
image = cv2.imdecode(np.fromfile(picPath,dtype=np.uint8),-1)

参考:

解决C++调用Python中文乱码_kpengk的博客-CSDN博客

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Qt C++调用 Python 的方法,可以使用 Python 的 C/C++ API 或者使用第三方库,如 Boost.Python 或 pybind11。这里提供使用 Python C/C++ API 的方法。 首先需要在 Qt C++ 项目中添加 Python 的头文件和库文件路径。在 .pro 文件中添加以下代码: ```pro INCLUDEPATH += /usr/include/python3.6m/ LIBS += -L/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu/ -lpython3.6m ``` 其中 `/usr/include/python3.6m/` 和 `/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu/` 是 Python 的头文件和库文件路径,需要根据实际情况进行修改。 然后在 Qt C++调用 Python 的方法,可以按照以下步骤进行: 1. 初始化 Python 解释器: ```c++ Py_Initialize(); ``` 2. 导入 Python 模块: ```c++ PyObject* pModule = PyImport_ImportModule("module_name"); ``` 其中 `"module_name"` 是 Python 模块的名称。 3. 获取 Python 方法: ```c++ PyObject* pFunc = PyObject_GetAttrString(pModule, "function_name"); ``` 其中 `"function_name"` 是 Python 方法的名称。 4. 调用 Python 方法: ```c++ PyObject* pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", "argument")); PyObject* pResult = PyObject_CallObject(pFunc, pArgs); ``` 其中 `"argument"` 是传递Python 方法的参数。需要注意的是,在 Py_BuildValue 函数中需要指定参数类型,例如使用 `"s"` 表示字符串类型。 5. 处理 Python 方法的返回值: ```c++ char* result; PyArg_Parse(pResult, "s", &result); ``` 其中 `"s"` 表示返回值的类型为字符串类型。 6. 释放 Python 对象: ```c++ Py_DECREF(pArgs); Py_DECREF(pResult); Py_DECREF(pModule); ``` 最后,在程序结束时需要清理 Python 解释器: ```c++ Py_Finalize(); ``` 以上是基础的调用 Python 方法的步骤,具体实现还需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值