首页 > 解决方案 > 如何将python字典传递给ac函数?

问题描述

我想在 python 代码中调用 ac 函数,并传入一个 python 字典作为参数。

小.c

#include <Python.h>
#include <stdio.h>
#include <stdlib.h>


PyObject *changeDict(PyObject *dict){


        if(PyDict_Check(dict) == 1){
                system("echo '==== is a dict ====' | systemd-cat -t 'little.c'");
        }

        // modify some value

        return dict;
}

我使用这些命令来编译 little.c:

gcc -g -fPIC -c little.c -I/usr/include/python2.7 -lpython2.7
gcc -shared little.o -o little.so

并移动到 LD_LIBRARY_PATH

mv little.so /usr/lib

小.py

from ctypes import *

mydll = PyDLL("little.so")

dic = {"status": 0}
dic = mydll.changeDict(dic)
print(dic)

python little.py

然后我得到了这个错误:

Traceback (most recent call last):
  File "little.py", line 13, in <module>
    dic = mydll.changeDict(dic)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1

是否可以将 python 字典直接传递给 C 函数?

标签: cpython-2.7ctypespython-c-api

解决方案


始终为您的函数定义.argtypes.restype,以便ctypes可以对参数进行类型检查并知道如何将它们编组到 C 和从 C 中编组。 py_object是直接传递 Python 对象时使用的类型。

工作示例:

// test.c
#include <Python.h>

__declspec(dllexport) // for Windows exports
PyObject *changeDict(PyObject *dict) {
    PyObject* value = PyUnicode_FromString("value");
    PyDict_SetItemString(dict, "key", value); // Does not steal reference to value,
    Py_DECREF(value);                         // so free this reference
    Py_INCREF(dict);   // because we're returning it...
    return dict;
}
# test.py
from ctypes import *

# Use PyDLL when calling functions that use the Python API.
# It does not release the GIL during the call, which is required
# to use the Python API.
mydll = PyDLL('./test')
mydll.changeDict.argtypes = py_object,  # Declare parameter type
mydll.changeDict.restype = py_object    # and return value.

dic = {}
x = mydll.changeDict(dic)
print(x)
dic = {'key':2}
mydll.changeDict(dic)  # Modified in-place, so really no need to return it.
print(dic)

输出:

{'key': 'value'}
{'key': 'value'}

推荐阅读