前言
第一次写笔记可能会有地方说的不是很清楚,如果有类似的问题可以在评论区和我沟通。
正文
这个笔记是默认你有一定的程序员基础的,未必是精通python或者C++的具体语法,但是不会出现像是路径写错、拼写错误等奇奇怪怪细节问题。
我这边是在公司CentOS7.4的服务器上进行的操作,服务器用的是3.6的python,gcc是4.9.2。
会看笔记的话应该是已经做过一些尝试了,如果是从零开始的话建议先看一下这篇 链接: link. 。我这边接下来主要是说一些我在实际使用中遇到的问题和解决办法,能力有限原理全靠猜。
import第三方库(例如librosa、numpy等)
如果你写了一个python文件,它import了很多个第三方库,这些库是需要你使用例如
PyRun_SimpleString("import numpy as np");
一个一个导入的。每一个外部库都需要使用PyRun_SimpleString()函数进行执行,这个函数相当于是一个宏定义(据说,我也没实际去看,但感觉差不多是把参数部分直接当做python语句执行一遍),所以定义在python函数外的全局变量也需要使用该语句进行定义。
好了到这里大部分人的问题已经解决了下面就不用看了www
顺带一提如果你编译通过了但是执行出现了问题,那欢迎翻阅第二条。
再顺带一提你在C++里调用PyRun_SimpleString()函数去执行的python语句在你的原文件里没必要删,反正不会被执行。
服务器权限问题
这个问题的主要解决办法是弄个anaconda虚拟环境,在这个虚拟环境下你可以很好的进行编译,但是有可能会遇到编译通过了但执行不通过的情况。
(从第一条来的看下面)
这个情况我的理解是你是用的是anaconda的gcc进行的编译(anaconda自动帮你管理了你所需要的外部库,例如librosa)但是执行用的是服务器的gcc(找不到你在anaconda环境下编译时链接的库)。
我尝试过编写run.sh然后使用export LD_LIBRARY_PATH=………/anaconda3/lib/………这种方法来进行,但是失败了,结果是在系统里重新安装了所需要的库。
编译问题
编译问题没啥好说的,ldd一下cpp文件看一下缺什么库编译的时候弄进去就好了,我的编译代码如下
g++ test_cpp_echo_py.cpp -I/work/env/include/python3.6m -L/work/anaconda3/lib -lpython3.7m -o testcpp
顺带一提你可能会好奇为什么我是-lpython3.7m,明明一开始说了系统是3.6的版本。。。enmmm别问,问就说不知道。哪个能用用哪个,不影响结果,但是不写不行=_=
参数传递问题
传参这个问题出现反正我这边是因为没有好好看官方文档或者我上面那条链接,我这里粘一下我自己写的部分
// PyObject* Py_BuildValue(char *format, ...)
// 把C++的变量转换成一个Python对象。当需要从
// C++传递变量到Python时,就会使用这个函数。此函数
// 有点类似C的printf,但格式不同。常用的格式有
// s 表示字符串,
// i 表示整型变量,
// f 表示浮点数,
// O 表示一个Python对象。
//初始化要传入的参数,args配置成传入两个参数的模式
PyObject* args = PyTuple_New(2);
PyObject* arg1 = Py_BuildValue("s","./");
PyObject* arg2 = Py_BuildValue("s","2020.wav");
//将arg1配置为arg带入的第一个参数
PyTuple_SetItem(args, 0, arg1);
//将arg1配置为arg带入的第二个参数
PyTuple_SetItem(args, 1, arg2);
//传入参数调用函数,并获取返回值
PyObject* pRet = PyObject_CallObject(pv, args);
传出的话如果是一个很复杂的东西其实我建议直接写进文件然后用C++去按规定格式读这个文件(反正我是这么干的),简单的字符串什么的可以看一下零基础那篇,里面传整形和字符串都有举例子。
结束
我主要遇到的问题就这几大块,也是刚开始弄,也是第一次写,具体的工程文件不方便贴出,有什么问题欢迎大家和我交流。