[英]How to call a builtin function (or method) from C code of a Python extension module?
我當前要完成的工作是在創建返回的組合之前,對Python的itertools
模塊函數combinations
進行調整,以對傳遞的iterable
進行排序,以對返回的組合進行排序。
我是第一次使用Python擴展模塊,到目前為止,我唯一的經驗是編寫和編譯類似於Python擴展模塊的“ Hello World”,但是我希望我在幾種編程語言中的總體編程經驗是我可以打下足夠堅實的基礎來成功應對這一挑戰。
我知道有一個內置的Python函數sorted()
可以對傳遞給combinations
的可迭代對象進行排序,但是我不知道如何在擴展模塊的C代碼中調用它。
我試過只寫iterable = sorted(iterable);
但是即使模塊已編譯(帶有警告),也無法通過ImportError: cgitertools.cpython-36m-x86_64-linux-gnu.so: undefined symbol: sorted
導入已編譯模塊ImportError: cgitertools.cpython-36m-x86_64-linux-gnu.so: undefined symbol: sorted
我的問題是:
如何從Python擴展模塊的C代碼中調用Python的內置方法(以
sorted()
為例sorted()
?
下面是我嘗試過的所有細節以及為何不起作用的詳細信息:
combinations_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
combinationsobject *co;
Py_ssize_t n;
Py_ssize_t r;
PyObject *pool = NULL;
PyObject *iterable = NULL;
Py_ssize_t *indices = NULL;
Py_ssize_t i;
static char *kwargs[] = {"iterable", "r", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "On:combinations", kwargs,
&iterable, &r))
return NULL;
// iterable.sort(); doesn't work ... cgitertoolsmodule.c:2398:13: error: request for member ‘sort’ in something not a structure or union
// iterable.__sort__(); doesn't work either with same error
// COMPILES, but gives ERROR on import in Python:
iterable = sorted(iterable);
$ python3.6 cgitertoolsmodule-setup.py build
running build
running build_ext
building 'cgitertools' extension
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC -I/usr/local/include/python3.6m -c cgitertoolsmodule.c -o build/temp.linux-x86_64-3.6/cgitertoolsmodule.o
cgitertoolsmodule.c: In function ‘combinations_new’:
cgitertoolsmodule.c:2400:16: warning: implicit declaration of function ‘sorted’ [-Wimplicit-function-declaration]
iterable = sorted(iterable);
^
cgitertoolsmodule.c:2400:14: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
iterable = sorted(iterable);
^
gcc -pthread -shared build/temp.linux-x86_64-3.6/cgitertoolsmodule.o -o build/lib.linux-x86_64-3.6/cgitertools.cpython-36m-x86_64-linux-gnu.so
$ python3.6
Python 3.6.1 (default, Apr 18 2017, 23:00:41)
[GCC 5.4.1 20160904] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from cgitertools import combinations
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cgitertools.cpython-36m-x86_64-linux-gnu.so: undefined symbol: sorted
您應該從內置函數中獲取排序后的函數,然后調用它:
PyObject *builtins = PyEval_GetBuiltins();
PyObject *sorted = PyDict_GetItemString(builtins , "sorted");
PyObject *sorted_list = PyEval_CallFunction(sorted, "(O)", iterable);
//... do something with the sorted_list
Py_DECREF(sorted_list);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.