青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

飯中淹的避難所~~~~~

偶爾來避難的地方~

  C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
  94 隨筆 :: 0 文章 :: 257 評論 :: 0 Trackbacks
項目里需要使用腳本,我是框架的維護人員,就需要把腳本系統加入到框架里。
因為對PYTHON比較熟悉,所以最后選擇了PYTHON作為腳本系統的主引擎。
下面是在這個過程中遇到的種種問題以及最后的解決方法。

1- 編譯出錯,提示找不到 __imp_Py_XXXX的引用
   這個問題真的很惡心,WIN版的PYTHON27.DLL用的是單線DLL的CRT,而項目如果用的是多線LIB的CRT,或者其他不兼容的CRT,就會出這個問題。
   果斷下載PYTHON2.7.2的源代碼,編譯之。然而,編譯過程也非常的惡心,工程屬性修改成MTd和MT仍舊不行。
   后看到編譯時有調用cl的命令行,找了半天在make_buildinfo這個項目里發現是使用代碼生成的編譯參數,里面寫死的是MDd,修改之再編譯,問題解決。

2- Py_Initialize 退出,提示無法找到site模塊。
    這個問題原本想暴力的修改源代碼里的nosite標記改之,后思考可能這個模塊是有用的,所以把運行過PYTHON.EXE的PYTHON運行路徑里的LIB里的被編譯成PYC的所有PY按路徑復制到EXE的路徑下,問題解決。

3- 不想用BOOST.PYTHON,又想不用寫PyCFunction的形式的C模塊方法
    這個問題經過分析,得到結論是,從任意形式的用戶函數生成一個PyObject*(*PYFUNC)(PyObject*,PyObject*)形式的函數封裝。并且對于一個獨立地址的用戶函數,需要一個獨立地址的函數封裝。
    首先,我開始解決如何從一個固定函數得到另一個固定地址函數。一開始我想到用函數地址作為模版參數,這樣每個獨立地址就能生成一個單獨的模版類,然后模版類里的靜態函數自然就是獨立地址的。后我使用了static的本地函數測試,未果,提示什么non-extra的錯誤。后進群詢問,得到同樣答案,并且編譯成功的結果。仔細觀察后發現,他用的是非static修飾的函數。我去掉static修飾,竟然成了。
    接下來,我開始解決如何從PyObject*args解析出用戶函數的每個參數的問題。這個問題有幾個部分,第一部分是如何從函數里析出每個參數,這部分我用了模版的某種特化,具體名字我不懂,就是如下面這種形式:
   
template <typename TR, typename T1 = void, typename T2 = void>
struct st_func {};
template 
<typename TR, typename T1>
struct st_func<TR, T1, void> {};

    這樣就可以析出返回值TR和各個參數的類型。為了支持盡可能多的參數,我寫了個程序生成了從0個參數到40個參數的模版變體。
    使用固定地址,因為函數定義需要TR,T1,所以函數指針無法直接在第一個模版參數傳遞,并且是固定參數,無法放在可選參數后面,所以我選擇了先在第一個參數用void*傳遞函數指針,然后在st_func內部用TR,T1...這些拼出一個函數指針,把首位置的指針強轉成原函數形式,再進行調用。
    因為PYTHON的解析函數需要每個參數的類型標識符,大部分類型是一個字符表示,這部分用了enum來為每個類型生成一個const且static的字符標識。比如
template <> struct type_char<int> { enum{ typechar = 'i' };};
    然后最終PyArg_ParseTuple 需要的是一個字符串,那么我在代碼里就 這樣來生成這個字符串:
   
char szTypes[] = { type_char<T1>::typechar, .., 0 };
    最后一個部分是解決TR是void時的函數返回值問題。后來我用了struct內部的特化函數來解決。最終形式如下:


template <void* FP, typename TR, typename T1>
struct st_cppfunc_to_py<FP, TR, T1, void, void>
{
typedef TR (
*TFP)(T1);
static PyObject * func( PyObject * self, PyObject * args ) { return _func<TR>( self, args ); }
template
<typename ITR>
static PyObject * _func( PyObject * self, PyObject * args ) {
char szType[] = { type_char<T1>::typechar, 0 };
T1 v1;
if( PyArg_ParseTuple( args, szType, &v1 ) ) {
TR ret
= ((TFP)FP)( v1 );
char szRetType[2] = { type_char<TR>::typechar, 0 };
return Py_BuildValue( szRetType, ret );
}
Py_RETURN_NONE;
}
template
<>
static PyObject * _func<void>( PyObject * self, PyObject * args ) {
char szType[] = { type_char<T1>::typechar, 0 };
T1 v1;
if( PyArg_ParseTuple( args, szType, &v1 ) ) {
((TFP)FP)( v1 );
}
Py_RETURN_NONE;
}

};

外面包一個  template <void*FP, typename TR, typename T1> PyCFunction __cppfunc2py( TR(*RFP)(T1) ) { return st_cppfunc_to_py<FP, TR, T1>::func; }

就可以很方便的生成嵌入PY的函數了。

4- 包裝的scriptvalue怎么獲得PyObject*的類型呢
    用Py_TYPE(ob)就可以獲取到object的typeobject,它的tp_name就是它的名字,常用類型 int, long, float, str 都可以分辨出來。

5- PYTHON的調試版總是報GC異常
    這個問題我是嘗試著來解決的,總結了以下幾點:
    a. 模塊的DICT是不用PY_XDECREF來釋放的   
    b. 返回值需要一個PY_XDECREF釋放。
    c. Py_BuildValue 返回值需要一個PY_XDECREF。
    d. 用戶模塊不需要 PY_XDECREF。
    e. PY文件生成的模塊需要一個 PY_XDECREF。
    f. Set Object到Tuple去調完PY的函數,PY_XDECREF(TUPLE)時,需要注意的是,Set進去的Object都會被調用一次Py_XDECREF,所以一個好的辦法是在Set進Tuple時,就INC一下他們的REF。
6- 為何一直調不到py文件里的函數
    這個問題困擾了我幾分鐘,模塊的method獲取不到,讓我一度以為是腳本寫的問題。
    后來我打印出來腳本的搜索路徑(print sys.path),是一大堆的路徑,我放進去的路徑排在最后。于是我想,是不是有的路徑下有重名的PY文件,就給文件改了個名字,結果就OK了。
    這個問題,我后來想可以通過調整搜索優先級來解決,不過目前還是這樣解決比較好,因為調整方法目前還不得而知。

   
posted on 2012-02-10 21:55 飯中淹 閱讀(3277) 評論(0)  編輯 收藏 引用
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区三区激情| 久久综合给合| 亚洲欧洲在线观看| 免费美女久久99| 亚洲精品视频在线播放| 亚洲免费播放| 国产精品v欧美精品∨日韩| 亚洲欧美日本国产专区一区| 亚洲一区二区三区成人在线视频精品| 亚洲另类在线一区| 在线亚洲美日韩| 日韩午夜剧场| 国产亚洲欧美一区二区| 免费日韩一区二区| 欧美日韩播放| 欧美制服丝袜第一页| 蜜桃久久av| 亚洲欧美激情视频| 久久久福利视频| 在线亚洲欧美专区二区| 西西裸体人体做爰大胆久久久| 在线免费观看视频一区| 99pao成人国产永久免费视频| 国产精品自拍网站| 欧美激情第3页| 国产欧美日韩综合| 亚洲高清影视| 国产情侣久久| 亚洲国产免费看| 国产亚洲人成网站在线观看| 亚洲精品日韩激情在线电影| 国产日韩欧美一区二区| 亚洲国产一区二区三区a毛片| 国产目拍亚洲精品99久久精品| 亚洲国产精品一区二区www在线| 国产精品普通话对白| 亚洲国产高清一区二区三区| 国产女人18毛片水18精品| 亚洲黄色成人| 在线观看一区二区精品视频| 亚洲制服丝袜在线| 亚洲视频一起| 欧美电影在线免费观看网站| 久久亚洲不卡| 国产日韩专区在线| 一区二区三区高清| aa国产精品| 欧美99在线视频观看| 久久野战av| 国产亚洲精品v| 亚洲影院免费| 亚洲免费影视| 欧美日在线观看| 亚洲欧洲精品一区二区三区| 在线成人激情视频| 欧美中文字幕在线视频| 久久国产99| 国产午夜精品久久久久久久| 亚洲一区二区三区午夜| 亚洲男人的天堂在线aⅴ视频| 欧美另类videos死尸| 91久久精品国产91久久性色| 亚洲精品在线二区| 欧美黄色小视频| 亚洲精品久久久久中文字幕欢迎你| 国内久久精品视频| 久久久青草青青国产亚洲免观| 久久久国产亚洲精品| 国产一区 二区 三区一级| 欧美亚洲日本网站| 久久蜜桃av一区精品变态类天堂| 国产色爱av资源综合区| 欧美在线播放| 欧美成人dvd在线视频| 亚洲人成在线免费观看| 欧美啪啪一区| 欧美日本不卡视频| 久久精品青青大伊人av| 狠狠综合久久| 欧美大片在线观看一区| 亚洲精品乱码久久久久| 亚洲免费视频成人| 国产一区二区三区黄| 久久久亚洲欧洲日产国码αv | 欧美韩日高清| 亚洲精选成人| 久久精品国产亚洲一区二区三区| 精品1区2区3区4区| 欧美精品一区二区三区很污很色的| 一本色道久久88亚洲综合88| 欧美资源在线| 亚洲一区二区三区四区在线观看| 久久精品在这里| 日韩视频亚洲视频| 国产农村妇女精品一二区| 狂野欧美激情性xxxx欧美| 99精品免费网| 久久夜色精品国产噜噜av| 99国产精品一区| 国产一区二区三区四区hd| 欧美成人一品| 欧美在线综合视频| 99re6热在线精品视频播放速度 | 在线日韩av片| 国产精品久久久久久久久久久久 | 亚洲午夜视频在线观看| 美日韩精品视频| 亚洲一区二区三区高清| 亚洲国产成人tv| 国产欧美一区二区色老头| 欧美本精品男人aⅴ天堂| 香蕉免费一区二区三区在线观看 | 欧美日韩国产在线播放| 久久精品欧美日韩| 中国成人在线视频| 欧美激情一区二区三区不卡| 久久精品国产在热久久| 亚洲性线免费观看视频成熟| 亚洲第一在线综合网站| 国产日韩欧美在线播放| 欧美三区美女| 欧美国产日韩在线| 久久人人爽人人爽爽久久| 新67194成人永久网站| 一区二区三区色| 亚洲欧洲日产国产网站| 免费在线观看精品| 久久久国产精品一区| 午夜一区二区三区在线观看| 一区二区三区三区在线| 亚洲日本中文字幕| 亚洲国产裸拍裸体视频在线观看乱了中文 | 欧美伊人久久久久久久久影院| 亚洲精品日韩在线观看| 亚洲丶国产丶欧美一区二区三区| 国产一区二区中文| 国产一区视频在线观看免费| 国产精品亚洲综合久久| 国产精品成人午夜| 国产精品美女一区二区在线观看 | 狂野欧美激情性xxxx欧美| 久久精品夜色噜噜亚洲aⅴ| 欧美一级日韩一级| 亚洲欧美国产视频| 亚洲欧美国内爽妇网| 亚洲女爱视频在线| 亚洲欧美日韩综合国产aⅴ| 亚洲女ⅴideoshd黑人| 午夜久久资源| 久久久久久电影| 麻豆精品视频在线观看| 免费在线观看日韩欧美| 欧美大片一区二区| 欧美日韩一区不卡| 国产精品高潮视频| 国产精品手机在线| 国产综合亚洲精品一区二| 一区二区在线看| 久久成人国产精品| 久久久久久九九九九| 欧美高清一区二区| 欧美午夜精品久久久久久孕妇| 欧美日韩在线直播| 国产亚洲激情视频在线| 亚洲第一综合天堂另类专| av成人免费在线| 欧美亚洲在线| 欧美二区在线播放| 一本一本久久a久久精品综合妖精| 亚洲夜晚福利在线观看| 久久精品主播| 欧美精品一级| 国产视频一区三区| 91久久国产综合久久91精品网站| 在线视频精品| 久久精品国产亚洲a| 亚洲高清视频中文字幕| 亚洲五月六月| 免费中文字幕日韩欧美| 国产精品xxx在线观看www| 亚洲成色www久久网站| 亚洲婷婷综合久久一本伊一区| 久久久久久精| 夜夜嗨av一区二区三区网页 | 亚洲天堂成人在线视频| 久久久噜噜噜久噜久久| 国产精品国码视频| 亚洲激情校园春色| 欧美一区二区三区视频免费| 亚洲国产经典视频| 欧美一区二区成人| 欧美三级欧美一级| 亚洲精品在线观看免费| 久久久国产一区二区三区| 亚洲免费精彩视频| 嫩草成人www欧美| 黑丝一区二区| 久久精品国产免费观看| 一区二区高清在线观看| 免费成人在线观看视频|