PyRun_SimpleString的无穷怨念
From: http://blog.csdn.net/ccat/article/details/544491
好吧,我承認(rèn)我是個菜鳥,所以今天我勇敢的站出來接受大家的鄙視……
話說早上同事喊我?guī)退亩纬绦?#xff0c;很簡單,就是用PyRun_SimpleString函數(shù)執(zhí)行一段Python腳本。錯誤也很直接,執(zhí)行的時候出現(xiàn)寫地址錯誤,如果你經(jīng)常用VC/Delphi寫一些用指針轉(zhuǎn)來轉(zhuǎn)去的程序,就應(yīng)該經(jīng)常見到這樣的錯誤。
所以,當(dāng)時我很鎮(zhèn)定。
嗯,我鎮(zhèn)定自若的指著屏幕(你看,那個時候這只手還很干燥)。吶,是不是文件訪問權(quán)限設(shè)得太高了?
同事答曰,我已經(jīng)試過所有的組合了。一邊說一邊給我看MSDN上的fopen函數(shù)說明。
那么……嗯,今天天氣真好啊……(嚴(yán)肅點(diǎn),我這兒思考問題呢)……那么,我們試試看……
在一番瞎折騰過后,我的直覺告訴我,這個不應(yīng)該是我同事的編碼有問題,大概是項(xiàng)目的什么配置或者干脆就是Python給出的API有問題。在看了同事從若干搜索引擎上找到的無數(shù)文章后,更確信這一點(diǎn)。于是我回到自己的座位上,打開Google,也開始搜索。
不找不知道,Python的資料這叫個亂噢……即使是英文文檔,也充滿了荒唐可笑的錯誤。有位達(dá)人還發(fā)表了這樣一段代碼:
?#include "Python.h"
int? main()
? {
??? Py_Initialize();
??? PyRun_SimpleFile("<filename>");
??? Py_Finalize();
??? return();
? }
呃……我的英文很差,也許我誤解了人家的意思,他其實(shí)是貼了份偽碼?反正這份代碼絕對是匪夷所思的。連PyRun_SimpleFile的參數(shù)表都對不上。本來就短到?jīng)]幾個字的文章,再配上這么“簡潔”的代碼,實(shí)在就沒什么營養(yǎng)了。
上面這個例子,只是我今天搜到的無數(shù)無用信息之一,在令我哭笑不得的混亂中,鬼知道哪個是有用的。唯一能確定的是,遇到這個問題的人還真挺多的……有人說這是個MSVC的使用問題,而不該當(dāng)作Python問題(嗯,提這個問題的都是用VC的,看來有道理);有人說這是因?yàn)?MD編譯選項(xiàng)沒打開,打開它就好了,于是我就在IDE中設(shè)置C++編譯器命令行,加上-MD,但是問題依舊(嗯,當(dāng)時我還在想,這個-MD是什么意思?難道編譯器也用漢語拼音講粗口?);還有人說,這個是因?yàn)関c運(yùn)行時庫方面,Python解釋器和開發(fā)者使用的不統(tǒng)一,所以出錯,根治的方法只有重編譯整個Python。啥也不說,我看了這個頭都大了。
讀過幾十篇不知道是不是惡搞的文章后,我的惡趣味上來了,在編譯了Python內(nèi)核的Debug版后,我開始了內(nèi)核跟蹤之旅。令人絕望的是,出錯的地方在內(nèi)核非常非常深入的地方,類似PyRun_ParseFile 之類的函數(shù),也就是說,如果真的是源碼有問題,那么整個Python就應(yīng)該根本不能在Windows上正常運(yùn)行。這顯然與我們所見的事實(shí)相違背。事實(shí)上,我真的把Python源碼中執(zhí)行腳本的那段復(fù)制出來,仍然不能使用。此時已經(jīng)是晚上,我的思路又回到了項(xiàng)目的設(shè)置,一樣的源代碼,Python項(xiàng)目編譯出來正常,我調(diào)用就有錯,這個很難說得通。于是我在項(xiàng)目設(shè)置中漫無目的的巡視著……
這這這,這是什么?
這不就是哪個什么什么粗口編譯選項(xiàng)么?在把項(xiàng)目選項(xiàng)頁中的“C/C++”·“運(yùn)行時庫”選項(xiàng)設(shè)置為多線程DLL(/MD)——調(diào)試狀態(tài)下為“多線程調(diào)試DLL(/MDd)”后,一切正常了!
呃,嚴(yán)肅點(diǎn)說,Python的Windows版都是以/MD,也就是多線程DLL模式編譯的,如果嵌入調(diào)用PyRun_SimpleFile,或者其它以解釋器執(zhí)行文件的API,都應(yīng)該把項(xiàng)目編譯成這個模式,不然就會發(fā)生內(nèi)存訪問錯誤。
呃……我的英文很差,也許我誤解了人家的意思,他其實(shí)是貼了份偽碼?反正這份代碼絕對是匪夷所思的。連PyRun_SimpleFile的參數(shù)表都對不上。本來就短到?jīng)]幾個字的文章,再配上這么“簡潔”的代碼,實(shí)在就沒什么營養(yǎng)了。
上面這個例子,只是我今天搜到的無數(shù)無用信息之一,在令我哭笑不得的混亂中,鬼知道哪個是有用的。唯一能確定的是,遇到這個問題的人還真挺多的……有人說這是個MSVC的使用問題,而不該當(dāng)作Python問題(嗯,提這個問題的都是用VC的,看來有道理);有人說這是因?yàn)?MD編譯選項(xiàng)沒打開,打開它就好了,于是我就在IDE中設(shè)置C++編譯器命令行,加上-MD,但是問題依舊(嗯,當(dāng)時我還在想,這個-MD是什么意思?難道編譯器也用漢語拼音講粗口?);還有人說,這個是因?yàn)関c運(yùn)行時庫方面,Python解釋器和開發(fā)者使用的不統(tǒng)一,所以出錯,根治的方法只有重編譯整個Python。啥也不說,我看了這個頭都大了。
讀過幾十篇不知道是不是惡搞的文章后,我的惡趣味上來了,在編譯了Python內(nèi)核的Debug版后,我開始了內(nèi)核跟蹤之旅。令人絕望的是,出錯的地方在內(nèi)核非常非常深入的地方,類似PyRun_ParseFile 之類的函數(shù),也就是說,如果真的是源碼有問題,那么整個Python就應(yīng)該根本不能在Windows上正常運(yùn)行。這顯然與我們所見的事實(shí)相違背。事實(shí)上,我真的把Python源碼中執(zhí)行腳本的那段復(fù)制出來,仍然不能使用。此時已經(jīng)是晚上,我的思路又回到了項(xiàng)目的設(shè)置,一樣的源代碼,Python項(xiàng)目編譯出來正常,我調(diào)用就有錯,這個很難說得通。于是我在項(xiàng)目設(shè)置中漫無目的的巡視著……
這這這,這是什么?
這不就是哪個什么什么粗口編譯選項(xiàng)么?在把項(xiàng)目選項(xiàng)頁中的“C/C++”·“運(yùn)行時庫”選項(xiàng)設(shè)置為多線程DLL(/MD)——調(diào)試狀態(tài)下為“多線程調(diào)試DLL(/MDd)”后,一切正常了!
呃,嚴(yán)肅點(diǎn)說,Python的Windows版都是以/MD,也就是多線程DLL模式編譯的,如果嵌入調(diào)用PyRun_SimpleFile,或者其它以解釋器執(zhí)行文件的API,都應(yīng)該把項(xiàng)目編譯成這個模式,不然就會發(fā)生內(nèi)存訪問錯誤。
最后,我要說的是,用PyRunSimpleFile函數(shù)調(diào)用Python腳本,真的很簡單,甚至可以簡單到如下這樣:
#include "python.h"int main(int argc, char *argv[]) {Py_Initialize();FILE * fp = NULL;fp = fopen("test.py", "r");if (fp == NULL) {return 1;}PyRun_SimpleFile(fp, "test.py");Py_Finalize();return 0; }我們不需要include系統(tǒng)I/O庫,Python.h中已經(jīng)封裝了這些東西,也不需要fclose,PyRun_SimpleFile已經(jīng)做了這一步,相信我,我在源代碼中看到了它。
寫下這篇文章,其實(shí)是想紀(jì)念下今天這個令我抓狂的遭遇,以及它戲劇性的收場,另外也感慨自己對日常使用的編譯器太不了解……現(xiàn)在總算知道-MD是什么意思,在哪里設(shè)置了,MD……
總結(jié)
以上是生活随笔為你收集整理的PyRun_SimpleString的无穷怨念的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 多线程锁--怎么理解Condition
- 下一篇: java获取中文拼音,java实现根据汉