PythonとC++の混合プログラミング実験


実験目的:
PythonがC++入力方式APIを呼び出す目的を実現
実験環境:
Ubuntu Kylin 15.10 Python 2.7.9 GCC 4.9.2
実験プロセス:
最初はC++とPythonのハイブリッドプログラミングを見て、最終的にPythonライブラリを拡張する案を選びました.Pythonの下層(?)について知りましたごみ回収言語のvariableはすべて引用されていますか?
編集(C)書き込み(P):
wrapper.cpp
fooはreturn list foo 1をテストしてパラメータタイプをテストするために使用されます
/**wrapper.cpp**/

#include <Python.h>
#include <cstdio>
static PyObject * ex_foo(PyObject *self, PyObject *args)
{
    printf("TYPE:%s
"
,Py_TYPE(args)->tp_name)
; // create the list PyObject* pList = PyList_New(3); // new reference assert(PyList_Check(pList)); // set some initial values for(int i = 0; i < 3; ++i) PyList_SetItem(pList, i, Py_BuildValue("i", i)); // insert an item PyList_Insert(pList, 2, Py_BuildValue("s", "inserted")); // append an item PyList_Append(pList, Py_BuildValue("s", "appended")); // sort the list PyList_Sort(pList); // reverse the list PyList_Reverse(pList); // fetch and manipulate a list slice PyObject* pSlice = PyList_GetSlice(pList, 2, 4); // new reference for(int j = 0; j < PyList_Size(pSlice); ++j) { PyObject *pValue = PyList_GetItem(pList, j); assert(pValue); } Py_DECREF(pSlice); return pList; } static PyObject * ex_foo1(PyObject *self, PyObject *args) { printf("PyTuple_Check:%d
"
,(int)PyTuple_Check(args))
; assert(PyTuple_Check(args)); printf("PyTupe_Size:%d
"
,(int)PyTuple_Size(args) )
; assert(PyTuple_Size(args) == 1); char *s=NULL; printf("s:%s
"
,s)
; printf("PyArg_ParseTuple:%d
"
,(int)PyArg_ParseTuple(args, "s", &s))
; if (!PyArg_ParseTuple(args, "s", &s)) PyErr_SetString(PyExc_TypeError, "invalid parameter"); Py_INCREF(args); return args; } static PyMethodDef example_methods[] = { {"foo", ex_foo, METH_VARARGS, "foo() doc string"}, {"foo1", ex_foo1, METH_VARARGS, "foo1() doc string"}, {NULL, NULL} }; PyMODINIT_FUNC initexample(void) { Py_InitModule("example", example_methods); }

setup.py
python setup.pyの使い方python setup.pyのアンインストール方法
#!./setup.py
from distutils.core import setup, Extension
example_mod = Extension('example', sources = ['wrapper.cpp'])
setup(name = "example",
    version = "1.0",
    description = "A sample extension module",
    ext_modules = [example_mod]
)

run.sh
#!./run.sh
python setup.py install --record log
echo "setup OVER"

実行
コマンドライン
>>> 
**@**:./test$ sudo sh run.sh
[sudo] password for voodoo: 
running install
running build
running build_ext
building 'example' extension
x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -fPIC -I/usr/include/python2.7 -c wrapper.cpp -o build/temp.linux-x86_64-2.7/wrapper.o
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
wrapper.cpp: In function ‘PyObject* ex_foo(PyObject*, PyObject*)’:
wrapper.cpp:24:19: warning: unused variable ‘pValue’ [-Wunused-variable]
         PyObject *pValue = PyList_GetItem(pList, j);
                   ^
c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wl,-Bsymbolic-functions -Wl,-z,relro -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/wrapper.o -o build/lib.linux-x86_64-2.7/example.so
running install_lib
copying build/lib.linux-x86_64-2.7/example.so -> /usr/local/lib/python2.7/dist-packages
running install_egg_info
Removing /usr/local/lib/python2.7/dist-packages/example-1.0.egg-info
Writing /usr/local/lib/python2.7/dist-packages/example-1.0.egg-info
writing list of installed files to 'log'
setup OVER

>>> **@**:./test$ python
>>> from example import *
>>> foo1("test")
PyTuple_Check:1
PyTupe_Size:1
s:(null)
PyArg_ParseTuple:1
('test',)
>>> foo1()
PyTuple_Check:1
PyTupe_Size:0
s:(null)
PyArg_ParseTuple:0
()
type(foo1)を使用して、戻り値のタイプを表示できます.私はこのように知っているパラメータのパラメータのタイプをインターネットで調べました.パラメータのタイプはtuple(メタグループ)です.PyArg_ParseTuple参考.