很抱歉,如果这太模糊了。我最近在阅读有关python的list.sort()方法的内容,并且因为性能原因读到它是用C语言编写的。
我假设python代码只是将列表传递给C代码并且C代码传回一个列表,但是python代码如何知道传递它的位置或者C给它正确的数据类型,以及C代码如何知道它给出的数据类型?
答案 0 :(得分:6)
Python可以用C / C ++进行扩展(更多信息here)
它基本上意味着您可以像这样包装C模块
#include "Python.h"
// Static function returning a PyObject pointer
static PyObject *
keywdarg_parrot(PyObject *self, PyObject *args, PyObject *keywds)
// takes self, args and kwargs.
{
int voltage;
// No such thing as strings here. Its a tough life.
char *state = "a stiff";
char *action = "voom";
char *type = "Norwegian Blue";
// Possible keywords
static char *kwlist[] = {"voltage", "state", "action", "type", NULL};
// unpack arguments
if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist,
&voltage, &state, &action, &type))
return NULL;
// print to stdout
printf("-- This parrot wouldn't %s if you put %i Volts through it.\n",
action, voltage);
printf("-- Lovely plumage, the %s -- It's %s!\n", type, state);
// Reference count some None.
Py_INCREF(Py_None);
// return some none.
return Py_None;
}
// Static PyMethodDef
static PyMethodDef keywdarg_methods[] = {
/* The cast of the function is necessary since PyCFunction values
* only take two PyObject* parameters, and keywdarg_parrot() takes
* three.
*/
// Declare the parrot function, say what it takes and give it a doc string.
{"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
"Print a lovely skit to standard output."},
{NULL, NULL, 0, NULL} /* sentinel */
};
使用Python头文件,它将定义和理解C / C ++代码中的入口点和返回位置。
答案 1 :(得分:1)
每个计算平台都有(或应该有)应用程序二进制接口(ABI)。这是如何在例程之间传递参数,返回值的方式,机器应处于什么状态等的规范。
ABI将指定诸如(例如):
之类的内容char
个对象),则会作为整数参数传递,如果它们很大,则会在堆栈中传递。每个编译器或其他语言实现都将生成符合ABI的代码,至少在其例程调用或从其他可能在语言之外的例程调用的情况下。
答案 2 :(得分:1)
我不能直接谈论Python / C交互,但我可以提供一些背景知道这些事情是如何工作的。
在特定平台或实现上,有一个 calling convention ,它指定如何将参数传递给子例程以及如何将值返回给调用者。针对该平台或实现的编译器和解释器生成符合该约定的代码,因此子例程/模块/用不同语言编写的任何内容都可以相互通信。
在我的汇编类中,我们有一个赋值,我们必须使用VAX汇编程序,C和Pascal编写程序(这是在白垩纪 1980年代)。驱动程序位于C或Pascal之一(不记得哪一个),它调用了程序集例程,它调用了另一个例程(用驱动程序没有的任何语言编写)。我们的汇编代码必须根据VMS调用约定从堆栈中弹出和推送参数。