Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从python代码调用C函数的最佳方法_Python_C - Fatal编程技术网

从python代码调用C函数的最佳方法

从python代码调用C函数的最佳方法,python,c,Python,C,我有一些C代码,它有一些基本的函数。我希望能够从python代码中调用这些C函数。当我在网上搜索时,似乎有很多方法可以做到这一点,但它们看起来有点复杂。有谁能建议哪种方法是从python调用C函数的最简单和最好的方法而没有任何问题吗?您可以使用C编译器使用共享库并调用库中定义的函数,为此,您可以使用模块CPython。假设您的C代码发送电子邮件,代码接受这样的参数 ./sendemail email title body 然后从python中,您可以执行以下操作: from subproces

我有一些C代码,它有一些基本的函数。我希望能够从python代码中调用这些C函数。当我在网上搜索时,似乎有很多方法可以做到这一点,但它们看起来有点复杂。有谁能建议哪种方法是从python调用C函数的最简单和最好的方法而没有任何问题吗?

您可以使用C编译器使用共享库并调用库中定义的函数,为此,您可以使用模块CPython。

假设您的C代码发送电子邮件,代码接受这样的参数

./sendemail email title body
然后从python中,您可以执行以下操作:

from subprocess import call
call(["./sendemail", "email@email.com", "subject", "body"])

Cffi库是一种相当现代的方法。它还可以跨python和pypy工作


如果您的函数包含在共享库中,您可以将它们作为python方法导入。看看这里的示例:

当您想用一些C函数扩展Python时,您可以查看以下示例。您需要的是一个模块,它为您自己的函数注册包装函数

有关更多信息,请查看

#包括
静态PyObject*
yourfunction(PyObject*self、PyObject*args、PyObject*keywds)
{
内部电压;
char*state=“僵硬”;
char*action=“voom”;
char*type=“挪威蓝”;
静态字符*kwlist[]={“电压”、“状态”、“动作”、“类型”,NULL};
如果(!PyArg_ParseTupleAndKeywords,args,keywds,“i|sss”,kwlist,
&电压、状态、动作和类型)
返回NULL;
printf(“--如果你把%i伏特加到这只鹦鹉身上,它就不会%s了。\n”,
动作电压);
printf(“--可爱的羽毛,%s--它是%s!\n”,类型,状态);
Py_增量(Py_无);
返回Py_None;
}
静态PyMethodDef keywdarg_方法[]={
{“yourfunction”,(PyCFunction)yourfunction,METH_VARARGS | METH_关键字,
“函数的文档”},
{NULL,NULL,0,NULL}/*哨兵*/
};
//在Python2.x中,函数名initmodulename在导入时执行
void initkeywdarg(void)
{
/*创建模块并添加函数*/
Py_InitModule(“keywdarg”,keywdarg_方法);
}
要编译该文件,可以使用clang。请记住,如果Python头位于其他位置,则必须更正include路径。创建的二进制文件
keywdarg。因此可以使用
import keywdarg
创建

clang++-shared-I/usr/include/python2.7-fPIC keywdarg.cpp-o keywdarg.so-lpython


这个问题是开放式的,会导致主观的答案,因此不适合使用stackoverflow。你可以在问你的问题。看看Cython,这并不是真正意义上的与C的集成。这只是使用命令行参数调用已编译程序。所有内容都必须转换为字符串或从字符串转换为字符串才能工作。根据OP的需要,这可能是一个可行的选择,但我认为你没有抓住要点。我写这个方法是因为OP似乎没有足够的知识将c代码导入python并运行它。@taesu这就是他问这个问题的原因-希望你不是暗示他不能学习新东西;)因此,我不希望他将c导入python,因此这种方式似乎相对更简单@我不是,我当然希望你是。你的两句话是对的,但它们之间没有逻辑关系。你的回答无助于OP解决他的问题。你链接到了文档中不好的部分,ABI级别非常危险,应该避免(除非你别无选择)。您不知道问题作者的库或操作系统。这可能很危险,也可能没问题。该文件列出了访问图书馆的各种方式。我剥离了abi的特定锚,但正是因为作者没有指定它,所以它和其他任何方法一样有效。(我的意思是,由于我们缺乏细节,他们最终将不得不做出选择。)
#include <Python.h>

static PyObject *
yourfunction(PyObject *self, PyObject *args, PyObject *keywds)
{
    int voltage;
    char *state = "a stiff";
    char *action = "voom";
    char *type = "Norwegian Blue";

    static char *kwlist[] = {"voltage", "state", "action", "type", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist,
                                     &voltage, &state, &action, &type))
        return NULL;

    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);

    Py_INCREF(Py_None);

    return Py_None;
}

static PyMethodDef keywdarg_methods[] = {
    {"yourfunction", (PyCFunction)yourfunction, METH_VARARGS | METH_KEYWORDS,
     "the doc of your function"},
    {NULL, NULL, 0, NULL}   /* sentinel */
};


// in Python 2.x the function name initmodulename is executed when imported
void initkeywdarg(void)
{
  /* Create the module and add the functions */
  Py_InitModule("keywdarg", keywdarg_methods);
}