根据Voo在这个帖子中的建议:
如何在Python执行函数时从C++中"hook into"它?我的目标是进行剖析
我开了一个新线程提出一个新问题,在C++中,如何初始化PythonInterpreter并调用其中的方法。具体来说,我想能够调用cProfile的方法并获取数据。
根据Voo在这个帖子中的建议:
如何在Python执行函数时从C++中"hook into"它?我的目标是进行剖析
我开了一个新线程提出一个新问题,在C++中,如何初始化PythonInterpreter并调用其中的方法。具体来说,我想能够调用cProfile的方法并获取数据。
好的,这可能需要更长一点时间。请注意,我基本上忽略了所有“通常”的错误检查 - 几乎任何Python方法都可能返回NULL,在这种情况下,您应该优雅地处理它。我展示了“不寻常”的部分,检查给定对象是否可调用。请注意,如果对象指针为NULL,则PyDECREF会失败,而Py_XDECREF则不会。现在来看代码 - 可能有更好的方法来解决所有这些问题,但对我来说,这个方法很好用,遗憾的是文档极其缺乏。
C++ 代码:
#include <Python.h>
static PyThreadState *mainstate;
void initPython(){
PyEval_InitThreads();
Py_Initialize();
mainstate = PyThreadState_Swap(NULL);
PyEval_ReleaseLock();
}
void exitPython(){
PyEval_AcquireLock();
PyThreadState_Swap(mainstate);
Py_Finalize();
}
void callScript() {
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject *pName = PyUnicode_FromString("Startup");
PyObject *pModule = PyImport_Import(pName);
Py_DECREF(pName);
PyObject *pFunc = PyObject_GetAttrString(pModule, "startup");
if (pFunc && PyCallable_Check(pFunc)) {
PyObject *arglist = Py_BuildValue("(u)", "TestScript");
PyObject *result = PyObject_CallObject(pFunc, arglist);
Py_DECREF(arglist);
// Now you have the returned object of the function - do something with it.
// In our case that's None, but you should extend the python scrip to return
// whatever you need - see the profiler API.
Py_DECREF(result);
}
Py_XDECREF(pFunc); // XDECREF does not fail if pointer is NULL.
Py_DECREF(pModule);
PyGILState_Release(gstate);
}
int main() {
printf("Start.\n");
initPython();
callScript();
exitPython();
printf("Exit.\n");
return 0;
}
你的特定脚本总是被调用,将其更改为以有用的方式返回所有所需数据 - 目前我们只使用cProfile.run()打印一些信息:
Startup.py
import cProfile
def startup(module_name):
print("Start script")
cProfile.run("import " + module_name)
print("Finished script")
最后执行的简单脚本:
TestScript.py
sum = 0
for i in range(10000):
sum += i