C嵌套python脚本调用心得

来源:互联网 发布:google keep windows 编辑:程序博客网 时间:2024/04/29 19:36

最近为工作需要,开发了一套多核性能功耗分析工具,其中涉及到大量数值分析,因此采用了界面用wtl,数据分析用python,数据源使用gator的组合方式加以实现。其中掉了几个小坑(十多分钟解决),记录如下:


1,每个公式使用一个独立的py,提供的接口能力不同,因此存在某函数不存在或者函数返回为空的情况,此时再一次生成数据的过程中,其它函数可能因此无法正确执行,需要在每次函数执行完,调用PyErr_clear,清除错误状态。


2,通过PySys_SetPath将公式所在目录加入py的执行路径里,此函数放在Py_Initialize();之后

    int len;    LPTSTR pos;    len = GetModuleFileName(_Module.m_hInst, szCurPath, sizeof(szCurPath));    pos = StrRChr(szCurPath, szCurPath+len, _T('\\'));    if(pos==0) return FALSE;    *pos = _T('\0');    StrCat(szCurPath, _T("\\formula\\"));    USES_CONVERSION;    if(!pypath[0])    {        strcpy_s(pypath, 4096, Py_GetPath());        strcat_s(pypath, 4096, ";");        strcat_s(pypath, 4096, T2A(szCurPath));    }     PySys_SetPath(pypath);

3,如果PyEval_CallObject出现莫名其妙的段错误,很有可能是在之前过度使用了Py_DECREF


4,在每个公式py文件下面,可以添加测试代码,用来调试py里面的bug

if __name__=="__main__":       setParam("coreid","1")       print “data:”,data()       print "eneryg:",energy()       print "tip:",tip()

5,  把计算放入线程,不要影响界面操作

DWORD __stdcall calcTrd( LPVOID lpThreadParameter){    CurveData *curve = reinterpret_cast<CurveData*>(lpThreadParameter);    CDataSource * ins = CurveData::engIns;    PyGILState_STATE state = PyGILState_Ensure( );....    PyGILState_Release( state );    return 0;}BOOL CDataSource::calc( CurveData & curve ){    Py_Initialize();    PySys_SetPath(pypath);    PyEval_InitThreads();    PyEval_ReleaseThread(PyThreadState_Get());    DWORD trid;    HANDLE handle = CreateThread(NULL, 0, calcTrd, &curve, 0, &trid);    MSG msg;    while(WaitForSingleObject(handle, 0) != WAIT_OBJECT_0)    {        CWaitCursor cursor;        if(GetMessage(&msg,NULL,0,0))        {            TranslateMessage(&msg);            DispatchMessage (&msg);        }        else        {            PostQuitMessage(0);        }    }    WaitForSingleObject(handle, INFINITE);    CloseHandle(handle);    PyGILState_Ensure();    Py_Finalize();    return TRUE;}

6, 仿照C的__FILE__:__LINE__效果:

def dbg():    try:        raise Exception    except:        return "%s:%d"%(os.path.basename(sys.exc_info()[2].tb_frame.f_back.f_code.co_filename),sys.exc_info()[2].tb_frame.f_back.f_lineno)


原创粉丝点击