2011-08-12 3 views
3

呼び出す:私はどのように私はPythonInterpreterを初期化することができ、C++では、新しい質問、のための新しいスレッドを開いているPythonインタプリタからメソッドこのスレッドにVOOのアドバイスあたり

How can I "hook into" Python from C++ when it executes a function? My goal is to profile

そこからメソッドを呼び出します。具体的には、私はcProfileのメソッドを呼び出し、そこからデータを取得できるようにしたいと思います。

答えて

0

もう少し長くなるでしょう。私がすべての「通常の」エラーチェックを無視していることに注意してください。ほとんどすべてのPythonメソッドはNULLを返すかもしれませんが、その場合は正常に処理する必要があります。私は、与えられたオブジェクトが呼び出し可能であるかどうかをチェックする "珍しい"部分を示します。オブジェクトポインタがNULL、Py_XDECREFがNULLでない場合、PyDECREFは失敗することに注意してください。そして今コードに - このすべてを解決するより良い方法があるかもしれませんが、これは私のためにうまくいきます。そして悲しいことに、ドキュメントは非常に不足しています。

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 
+0

おかげVOO、私はこれをもう少し詳しく読む必要がありますが、あなたは私を大いに助けてくれました。もう一度ありがとう:) – easythrees

+1

かなり複雑なコードとその午前3時から一緒に作成したので、私はここで何か間違いがないことを願っています。私のために寝る時間:) – Voo

関連する問題