目录

Python-3-输出重定向使用CC

目录

Python 3 输出重定向使用C/C++

Python 3 **输出重定向使用

C/C++**

By:gddsky

目标

希望将

Python 3

的输出重定向到自定义的输出目标。

核心

Python

使用

sys.stdout

sys.stderr

做输出目标,只要我们替换这两个值就可以重定向到我们自定义目标。替换的值的规则在

Python

的文档中

sys (module)

sys.stdout

上面说明只要添加一个

write

函数就可以了。像这样:

write(self, str)

我们只要在这个函数里面调用我们自己的输出函数就可以实现该目标了。

方案

C++

中写一个

Python

模块,并导入

C++

中利用

PyRun_SimpleString

建立一个

PyObject

去替换原始的

sys.stdout

sys.stderr

搞定!!!

代码

模块定义部分代码(用

python demo

下的例子改写的)

static

PyObject * console_write ( PyObject * self , PyObject * args )

{

if ( s_pyConsoleNotify != NULL )

{

const

char * pMsgString =0;

if (! PyArg_ParseTuple ( args , “s” , & pMsgString ))

{

return

NULL ;

}

//

我们自己的输出函数

myprint(pMsgString);

}

Py_INCREF ( Py_None );

return

Py_None ;

}

static

PyMethodDef

console_methods [] = {

{

“test” ,

console_test ,

METH_NOARGS , “Return the meaning of everything.” },

{

“write” ,

console_write ,

METH_VARARGS , NULL },

{

NULL ,

NULL }

/* sentinel */

};

static

struct

PyModuleDef

consolemodule = {

{}, /* m_base */

“console_capi” ,

/* m_name */

0,

/* m_doc */

0,

/* m_size */

console_methods ,

/* m_methods */

0,

/* m_reload */

0,

/* m_traverse */

0,

/* m_clear */

0,

/* m_free */

};

PyObject

PyInit_console ( void )

{

return

PyModule_Create (& consolemodule );

}

C++

执行的

Python

代码

void myOutput()

{

PyImport_AppendInittab ( “console_capi” , PyInit_console );

Py_Initialize ();

PyRun_SimpleString (

“import sys/n”

“import console_capi/n”

“class XConsole:/n”

"

def write(self, s):/n"

"

console_capi.write(s)/n"

//

这里将输出信息转给 console_write 函数

“myconsole = XConsole()/n”

“sys.stdout = myconsole/n”

“sys.stderr = myconsole”

);

}

经验

用 PyArg_ParseTuple 函数做参数解析,怎么都是错误的,最后才发现原来是因为 python 的脚本里面写的 console_capi.write(

self

, s)

,以为 console_write

( PyObject * self , PyObject * args )

的 self 就是由脚本中的这个 self 传进来了,结果这个 self 与脚本的 self 不一样,它是 module 的 PyObject ,将 console_capi.write(

self

, s)

改成 console_capi.write(s) 之后,解析就对了。

在 C++ 中,可以看 PyObject 结构,里面有一个 ob_type.tp_name 的值,它直接显示这个 Object 是什么类型,比如说 module 、 str 、 tuple ,这个值让我们可以很方便的得到这个 Object 的类型,调试比较方便。

一些问题实在麻烦,可以考虑直接下 source 版本编译 Debug 来调试,有些问题处理还是比较方便。