出于某些原因,我不得不扩展python的ssl模块。特别是我需要C语言中的第二个版本的load_cert_chain()。
我的问题与openssl无关,而是如何处理“诊所”:
在原始函数前面有一个诊所输入:

/*[clinic input]
_ssl._SSLContext.load_cert_chain
certfile: object
keyfile: object = NULL
password: object = NULL

[clinic start generated code]*/

static PyObject *
_ssl__SSLContext_load_cert_chain_impl(PySSLContext *self, PyObject *certfile,
                                  PyObject *keyfile, PyObject *password)
/*[clinic end generated code: output=9480bc1c380e2095 input=7cf9ac673cbee6fc]*/
{
    PyObject *certfile_bytes = NULL, *keyfile_bytes = NULL;
    pem_password_cb *orig_passwd_cb = self->ctx->default_passwd_callback;
    ...

到目前为止,我知道,ssl-SSLContext-load-cert-chain是load-cert-chain的实现,并在ssl-SSLContext-load-cert-chain中调用,它在头文件ssl.c.h中定义
然而,这是由诊所自动生成的,不是吗?
既然所有东西都是自动创建的,那么我从哪里开始将新函数load_cert_chain2定义为原始函数的副本呢?

最佳答案

为了澄清一些误解:
不,参数诊所与将C函数链接到Python函数无关!
参数诊所只是为C函数创建一个函数签名。在你的例子中

/*[clinic input]
_ssl._SSLContext.load_cert_chain
certfile: object
keyfile: object = NULL
password: object = NULL

_ssl__SSLContext_load_cert_chain_implC函数将在签名中公开为_ssl._SSLContext.load_cert_chain,其中三个参数应使用pythonobjectcertfile作为位置参数,keyfile, password作为默认值为NULL的可选参数。
函数的调用方式或调用时间未链接到参数诊所。方法声明在Modules/clinic/_ssl.c.h中完成:
#define _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF    \
    {"load_cert_chain", (PyCFunction)_ssl__SSLContext_load_cert_chain, METH_FASTCALL, _ssl__SSLContext_load_cert_chain__doc__}

static PyObject *
_ssl__SSLContext_load_cert_chain(PySSLContext *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
{
    [...]
    return_value = _ssl__SSLContext_load_cert_chain_impl(self, certfile, keyfile, password);
}

它作为方法显式地添加到_SSLContext中的Modules/_ssl.c类中:
static struct PyMethodDef context_methods[] = {
    [...]
    _SSL__SSLCONTEXT_LOAD_CERT_CHAIN_METHODDEF
    [...]
    {NULL, NULL}        /* sentinel */
};

[...]

static PyTypeObject PySSLContext_Type = {
    PyVarObject_HEAD_INIT(NULL, 0)
    "_ssl._SSLContext",                        /*tp_name*/
    sizeof(PySSLContext),                      /*tp_basicsize*/
    [...]
    context_methods,                           /*tp_methods*/
    [...]
};

因此参数诊所不负责将方法分配给类。这是用包装函数_ssl__SSLContext_load_cert_chain_ssl__SSLContext_load_cert_chain_impl附近完成的,并使用分配给类的PyMethodDef结构分配给类。
现在你知道没有自动生成的链接了,我不知道当你想替换那个函数的时候这是否有帮助。我不知道在不重新编译Python或将所有相关文件复制到扩展名中的情况下,如何轻松地做到这一点(参数诊所或不诊所)。

09-16 23:09