`
v5qqcom
  • 浏览: 1276709 次
文章分类
社区版块
存档分类
最新评论

PyRun_SimpleString的无穷怨念

 
阅读更多

好吧,我承认我是个菜鸟,所以今天我勇敢的站出来接受大家的鄙视……

话说早上同事喊我帮他改段程序,很简单,就是用PyRun_SimpleString函数执行一段Python脚本。错误也很直接,执行的时候出现写地址错误,如果你经常用VC/Delphi写一些用指针转来转去的程序,就应该经常见到这样的错误。

所以,当时我很镇定。

嗯,我镇定自若的指着屏幕(你看,那个时候这只手还很干燥)。呐,是不是文件访问权限设得太高了?

同事答曰,我已经试过所有的组合了。一边说一边给我看MSDN上的fopen函数说明。

那么……嗯,今天天气真好啊……(严肃点,我这儿思考问题呢)……那么,我们试试看……

在一番瞎折腾过后,我的直觉告诉我,这个不应该是我同事的编码有问题,大概是项目的什么配置或者干脆就是Python给出的API有问题。在看了同事从若干搜索引擎上找到的无数文章后,更确信这一点。于是我回到自己的座位上,打开Google,也开始搜索。

不找不知道,Python的资料这叫个乱噢……即使是英文文档,也充满了荒唐可笑的错误。有位达人还发表了这样一段代码

<!--StartFragment -->#include "Python.h"

int main()
{
Py_Initialize();
PyRun_SimpleFile("<filename>");
Py_Finalize();
return();
}

呃……我的英文很差,也许我误解了人家的意思,他其实是贴了份伪码?反正这份代码绝对是匪夷所思的。连PyRun_SimpleFile的参数表都对不上。本来就短到没几个字的文章,再配上这么“简洁”的代码,实在就没什么营养了。

上面这个例子,只是我今天搜到的无数无用信息之一,在令我哭笑不得的混乱中,鬼知道哪个是有用的。唯一能确定的是,遇到这个问题的人还真挺多的……有人说这是个MSVC的使用问题,而不该当作Python问题(嗯,提这个问题的都是用VC的,看来有道理);有人说这是因为-MD编译选项没打开,打开它就好了,于是我就在IDE中设置C++编译器命令行,加上-MD,但是问题依旧(嗯,当时我还在想,这个-MD是什么意思?难道编译器也用汉语拼音讲粗口?);还有人说,这个是因为vc运行时库方面,Python解释器和开发者使用的不统一,所以出错,根治的方法只有重编译整个Python。啥也不说,我看了这个头都大了。

读过几十篇不知道是不是恶搞的文章后,我的恶趣味上来了,在编译了Python内核的Debug版后,我开始了内核跟踪之旅。令人绝望的是,出错的地方在内核非常非常深入的地方,类似PyRun_ParseFile 之类的函数,也就是说,如果真的是源码有问题,那么整个Python就应该根本不能在Windows上正常运行。这显然与我们所见的事实相违背。事实上,我真的把Python源码中执行脚本的那段复制出来,仍然不能使用。此时已经是晚上,我的思路又回到了项目的设置,一样的源代码,Python项目编译出来正常,我调用就有错,这个很难说得通。于是我在项目设置中漫无目的的巡视着……

这这这,这是什么?

Embeding By PyRun_SimpleFile

这不就是哪个什么什么粗口编译选项么?在把项目选项页中的“C/C++”·“运行时库”选项设置为多线程DLL(/MD)——调试状态下为“多线程调试DLL(/MDd)”后,一切正常了!

呃,严肃点说,Python的Windows版都是以/MD,也就是多线程DLL模式编译的,如果嵌入调用PyRun_SimpleFile,或者其它以解释器执行文件的API,都应该把项目编译成这个模式,不然就会发生内存访问错误。

呃……我的英文很差,也许我误解了人家的意思,他其实是贴了份伪码?反正这份代码绝对是匪夷所思的。连PyRun_SimpleFile的参数表都对不上。本来就短到没几个字的文章,再配上这么“简洁”的代码,实在就没什么营养了。

上面这个例子,只是我今天搜到的无数无用信息之一,在令我哭笑不得的混乱中,鬼知道哪个是有用的。唯一能确定的是,遇到这个问题的人还真挺多的……有人说这是个MSVC的使用问题,而不该当作Python问题(嗯,提这个问题的都是用VC的,看来有道理);有人说这是因为-MD编译选项没打开,打开它就好了,于是我就在IDE中设置C++编译器命令行,加上-MD,但是问题依旧(嗯,当时我还在想,这个-MD是什么意思?难道编译器也用汉语拼音讲粗口?);还有人说,这个是因为vc运行时库方面,Python解释器和开发者使用的不统一,所以出错,根治的方法只有重编译整个Python。啥也不说,我看了这个头都大了。

读过几十篇不知道是不是恶搞的文章后,我的恶趣味上来了,在编译了Python内核的Debug版后,我开始了内核跟踪之旅。令人绝望的是,出错的地方在内核非常非常深入的地方,类似PyRun_ParseFile 之类的函数,也就是说,如果真的是源码有问题,那么整个Python就应该根本不能在Windows上正常运行。这显然与我们所见的事实相违背。事实上,我真的把Python源码中执行脚本的那段复制出来,仍然不能使用。此时已经是晚上,我的思路又回到了项目的设置,一样的源代码,Python项目编译出来正常,我调用就有错,这个很难说得通。于是我在项目设置中漫无目的的巡视着……

这这这,这是什么?

Embeding By PyRun_SimpleFile

这不就是哪个什么什么粗口编译选项么?在把项目选项页中的“C/C++”·“运行时库”选项设置为多线程DLL(/MD)——调试状态下为“多线程调试DLL(/MDd)”后,一切正常了!

呃,严肃点说,Python的Windows版都是以/MD,也就是多线程DLL模式编译的,如果嵌入调用PyRun_SimpleFile,或者其它以解释器执行文件的API,都应该把项目编译成这个模式,不然就会发生内存访问错误。

最后,我要说的是,用PyRunSimpleFile函数调用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系统I/O库,Python.h中已经封装了这些东西,也不需要fclose,PyRun_SimpleFile已经做了这一步,相信我,我在源代码中看到了它。

写下这篇文章,其实是想纪念下今天这个令我抓狂的遭遇,以及它戏剧性的收场,另外也感慨自己对日常使用的编译器太不了解……现在总算知道-MD是什么意思,在哪里设置了,MD……



  


  
分享到:
评论

相关推荐

    TK-News.pyrun-main.py

    TK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News.pyrun_main.pyTK_News....

    c语言调用python脚本

    然后可以使用PyRun_SimpleString函数执行Python脚本,或者使用PyRun_SimpleFile函数执行指定的Python脚本文件。 下面是一个简单的示例代码: c #include int main() { // 初始化Python解释器 Py_Initialize();...

    run-main.pyrun-main.py

    run_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main.pyrun_main....

    Python库 | pandoc_pyrun-1.0.2.tar.gz

    python库。 资源全名:pandoc_pyrun-1.0.2.tar.gz

    tictactoe_mcts:使用蒙特卡洛树搜索玩tietactoe游戏

    项目说明这是一个使用python实现的蒙特卡罗树搜索玩TicTacToe游戏,这里主要参考了一篇文件说明项目中有四个文件game.pyhuman.pymcts.pyrun_tictactoe.py比较重要的是game.py 和 mcts.py 文件。在game.py 中主要包含...

    busybox-python:Busybox容器和rootfs构建器,用于使用Python生成最少的Docker基础映像

    busybox-python Busybox 1.22.1 (带有Buildroot 2014.11 )容器和r​​ootfs构建器,用于最小的Docker基础映像,该... Python解释器由eGenix PyRun:trade_mark:提供支持。 easy_install版本0.7.4是该映像的一部分。

    TexasPokerRobot:华为软件竞赛 德州扑克

    TexasPokerRobot华为软件竞赛 德州扑克Installationgit clone --recursive git@github.com:yutianqiuhao/TexasPokerRobot.git gamecd game/works/libs/holdem_calc/touch __init__.pyRUN./RobotTest.sh

    Unity3D-Python:在Unityy里使用Python脚本

    Unity3D-Python编辑器 在unity3d里使用python unity版本5.6.1 注意 我这是用@cesardeazevedo那里弄到的,然后我精简了一下,现在只需要放置一下就可以用了。... public string pyFilePath="Assets/src/python/

    docker:码头食谱的集合

    elyase/pyrun :基于pyrun仅18.44 MB的 Python 小型pyrun 。 elyase/conda :轻量级但功能齐全的 python conda 图像。 如果您想使用 conda 包装系统发光的科学堆栈(numpy、pandas、ipython、sklearn),则建议...

    ACPL:我自己的编程语言(用Python编译)

    ACPL 我自己的编程语言(用Python解释)。 这个项目只是为了娱乐,练习而创建的,实际上是有用的... pyrun :运行指定的python文件 compile :将ACPL文件编译为Python文件 ini-content :显示ini文件的内容。 ope

    Learning a Deep Convolutional Network for Image Super-Resolution论文分析与pytorch代码

    linear mapping 非线性映射Reconstruction训练测试实验结果Pytorch代码实现使用说明文件存放运行代码model.pydata.pymain.pyrun.py运行操作图片对比Original imageBicubic imageSRCNN image后续工作参考文章 ...

Global site tag (gtag.js) - Google Analytics