如何将python中的dict作为参数传入c函数中用c做相关的处理?

如建议用PyArg_ParseTuple(args,"i",&com)类型处理具体要怎么做,做好能有例子做参考,谢谢... 如建议用PyArg_ParseTuple(args, "i", &com)类型处理具体要怎么做,做好能有例子做参考,谢谢 展开
 我来答
百度网友29d79c26e1
2014-08-13 · TA获得超过665个赞
知道小有建树答主
回答量:150
采纳率:0%
帮助的人:96.3万
展开全部
#先上代码再解释
static PyObject *keywdarg_parrot(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[] = {
    /* The cast of the function is necessary since PyCFunction values
     * only take two PyObject* parameters, and keywdarg_parrot() takes
     * three.
     */
    {"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
     "Print a lovely skit to standard output."},
    {NULL, NULL, 0, NULL}   /* sentinel */
};

PyObject * initkeywdarg(void)
{
  /* Create the module and add the functions */
  return Py_InitModule("keywdarg", keywdarg_methods);
}

这是一个函数(keywdarg_parrot)即使用了元组参数,也使用了字典参数的例子。例子出自Python2.7.2的文档。具体在:

Python v2.7.2 documentation »Extending and Embedding the Python
Interpreter

这个页面下。文档里面有一些关于C/C++与Python交互的介绍和例子,还是比较详细的。传递字典参量要注意,

{"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS,
     "Print a lovely skit to standard output."},

这里的METH_VARARGS | METH_KEYWORDS,与普通的不同。解析用:

PyArg_ParseTupleAndKeywords(args, keywds, "i|sss", kwlist,
                                     &voltage, &state, &action, &type)

其中的四个变量要提前声明好,这里分别是int,str,str,str类型的。int对应的是args接受到的值。string的都是keywds里面的,它们都是有初始值的。kwlist是变量的名字,就是在python里调用的时候使用的keyword名称。照着例子的模式可以改成其它的,能用的。具体是怎么工作的,其实我也太明白。

Python代码是这样的调用的时候:

print keywdarg.parrot(10,"LHJ",'HKJ','ER')
print keywdarg.parrot(10,"LHJ",'HKJ')
print keywdarg.parrot(10,"LHJ",type='KJ')

输出分别是:

-- This parrot wouldn't HKJ if you put 10 Volts through it.

-- Lovely plumage, the ER -- It's LHJ!

None

-- This parrot wouldn't HKJ if you put 10 Volts through it.

-- Lovely plumage, the Norwegian Blue -- It's LHJ!

None

-- This parrot wouldn't voom if you put 10 Volts through it.

-- Lovely plumage, the KJ -- It's LHJ!

None

第二次调用省略掉了变量,也能正常执行。第三次调用,变量type本来是第四位的,现在变成了keyword并写在了第三位,是python代码里调用的常见形式:keyword不讲顺序,省略掉的keyword使用了默认值。

就这些了,其它的你再看一下Python的文档吧。

追问
我要的是这种形式:keywdarg.parrot({...})   即传值进去的是个字典?如果是你这样的话那我要在keywdarg_parrot()函数中就要知道有哪些key和key的类型,这样是不行的?
追答

PyArg_ParseTuple,就是用来解析像f(x,y,z)这样的一行变量的,又不是用来解析f((x,y,z))这样只有一个元组作为变量的(虽然在Python里可以用f(*(x,y,z))解包)。你的问题描述很好表达了你的意思,但是你的例子举差了,误导人。如果你不知道类型的话,你根本就没有办法往C语言里面传数据。因为C是必须要声明数据类型的,又不像Python可以无视类型。dict={'s':2,1:'a',(2,3):[42,43]}这个字典要转化成C类型将是很悲剧的。参数是一个字典也可以用magic方法变成参数字典:

def f(x=3,y=4):
     print x,y
dict={'x':6,'y':43}
f(**dict)
#6 43

但是,如果一个很长的dict的话。干嘛不直接使用PyObject然后用PyDict_GetItem来调用其中的值,还parse干嘛。虽然这样速度会慢一些,但是可以一次处理完,保存为C的数据类型,然后再调用。



PyObject* PyDict_GetItemString(PyObject *p, const char *key) 

这个是对于key是字符串的字典可以使用的,在C中使用字符串调用,返回一个PyObject。


PyObject* PyDict_GetItem(PyObject *p, PyObject *key)

这个可以调用任何类型的字典,前提是需要先打包一个PyObject的key。


下面是迭代,也是出自官方文档,里面也有例子,字数限制,贴不上了。

int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)


下面是直接传PyObject的例子。

PyObject *handle_fun(PyObject *self, PyObject *args,void fun())
{
   PyObject *pDict;
   if (PyArg_UnpackTuple(args,"ref", 1, 1,&pDict)) //主要是这里的,解析为一个PyObject
   {
       //do something with pDict...
   }
}

希望这次回答到点子上了。

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式