3

我有兴趣在 C 程序中使用 Python 日志记录模块。我已经尝试阅读http://docs.python.org/2/extending/embedding.html上的文档,但我很困惑。

这就是我想要完成的(Python 等价物):

import logging, logging.handlers
logger = logging.getLogger('')
logger.setLevel(logging.DEBUG)
socketHandler = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)
logger.addHandler(socketHandler)
logger.debug("whats up, doc?")

这是我在 C 中尝试的:

PyObject *logging, *get_logger, *pValue, *set_level, *strargs;
*logging = PyImport_ImportModule("logging")
*get_logger = PyObject_GetAttrString(logging, "getLogger")
*pValue = PyObject_CallObject(get_logger, NULL)
*set_level = PyObject_GetAttrString(logging, "setLevel")
*strargs = PyString_FromString("logging.DEBUG")
pValue = PyObject_CallObject(set_level, strargs);

不过,我不确定如何创建 socketHandler。有什么提示吗?谢谢!

4

1 回答 1

1

在 Python C API 中,就像在 Python 中一样,“创建对象”只是调用它的类型

不幸的是,getattr用 C 语言做所有的事情真的很烦人。根据您想从 C 中执行的操作,您可以提供一堆在导入时传递给 C 的帮助模块(请参阅https://github.com/couchbase/couchbase-python-client/blob/master/couchbase /_bootstrap.py为例)。

无论如何,Python 是一门非常简单的语言,无论是从内到外。因此,让我们分解一下。

socketHandler = logging.handlers.SocketHandler('localhost', logging.handlers.DEFAULT_TCP_LOGGING_PORT)

PEP-7 说 C89,但在 C99 中更容易显示:

PyObject *logging = PyImport_ImportModule("logging");
PyObject *handlers = PyObject_GetAttrString(logging, "handlers");

现在,构建套接字处理程序。从 C API 调用某些东西可以用 PyObject_CallObject 来完成,它适用于任何已经__call__ 定义的东西 首先,你需要构建 thr 参数。

PyObject *sh_ctor = PyObject_GetAttrString(handlers, "SocketHandler");
PyObject *args = Py_BuildValue("(si)", "localhost", DEFAULT_LOGGING_PORT)
PyObject *sh_instance = PyObject_CallObject(sh_ctor, args);

我不会在这里展示如何进行 arg 构建,甚至不会展示正确的错误检查或引用计数。请注意,在 C API 中,如果函数失败,它会返回NULL并引发异常(除非另有说明)。

实际上,我建议的是弄清楚logging您实际上需要从 C 中使用多少模块,并将该功能包装在一个更简单的子集中,您可以从 C 中调用该子集。请参阅_bootstrap.py上面链接到的模块。

于 2013-10-18T00:03:53.987 回答