Python から C の呼出し
C のコードを Python から呼出せないかと…
Python のドキュメントとしては次の所にある
C や C++ による Python の拡張
Win10 C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\include\Python.h debian10 /usr/include/python3.7/Python.h AS5202T /volume1/.@plugins/AppCentral/python3/include/python3.7m/Python.h Iwao@AS5202T:/volume1/.@plugins/AppCentral/python3/include/python3.7m $ find / -name Python.h /volume1/.@plugins/AppCentral/linux-center/containers/debian10/rootfs/usr/include/python2.7/Python.h /volume1/.@plugins/AppCentral/linux-center/containers/debian10/rootfs/usr/include/python3.7m/Python.h /volume1/.@plugins/AppCentral/python/include/python2.7/Python.h /volume1/.@plugins/AppCentral/python3/include/python3.7m/Python.h
検索 して見つけたもの.
https://www.fsi-embedded.jp/kumico/columns/?cat=python
https://qiita.com/donkonishi/items/b7825b34d0711e336c61
https://www.quark.kj.yamagata-u.ac.jp/~hiroki/python/?id=19
http://owa.as.wakwak.ne.jp/zope/docs/Python/BindingC/
https://cpp-learning.com/?s=”Python+C+API”
Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello/bak $ cat hellWrap.c #include <Python.h> extern int add(int, int); extern void out(const char*, const char*); PyObject* hello_add(PyObject* self, PyObject* args) { int x, y, g; if (!PyArg_ParseTuple(args, "ii", &x, &y)) return NULL; g = add(x, y); return Py_BuildValue("i", g); } PyObject* hello_out(PyObject* self, PyObject* args, PyObject* kw) { const char* adrs = NULL; const char* name = NULL; static char* argnames[] = {"adrs", "name", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kw, "|ss", argnames, &adrs, &name)) return NULL; out(adrs, name); return Py_BuildValue(""); } static PyMethodDef hellomethods[] = { {"add", hello_add, METH_VARARGS}, {"out", hello_out, METH_VARARGS | METH_KEYWORDS}, {NULL} }; void initchello(){ Py_InitModule("hello", hellomethods); } Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello/bak $ gcc -fPIC -Wall -c -o hellWrap.o hellWrap.c -I /volume1/.@plugins/AppCentral/python/include/python2.7/ hellWrap.c:30:13: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types] {"out", hello_out, METH_VARARGS | METH_KEYWORDS}, ^~~~~~~~~ hellWrap.c:30:13: note: (near initialization for 'hellomethods[1].ml_meth') Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello/bak $ gcc -fPIC -Wall -c -o hellWrap.o hellWrap.c -I /volume1/.@plugins/AppCentral/python/include/python2.7/ Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello/bak $
PyMethodDef の所でエラーとなっていていろいろと探すと,型を指定しているものがあり,それを指定.
https://bty.sakura.ne.jp/wp/archives/83
static PyMethodDef hellomethods[] = { {"add", (PyCFunction)hello_add, METH_VARARGS}, {"out", (PyCFunction)hello_out, METH_VARARGS | METH_KEYWORDS}, {NULL} };
コンパイルは通る様になった.
Python から試そうとすると …
Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello $ gcc -fPIC -Wall -c -o helloWrap.o helloWrap.c -I /volume1/.@plugins/AppCentral/python/include/python2.7/ Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello $ gcc -fPIC -Wall -shared -o hellomodule.so hello.o helloWrap.o Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello $ ll total 44 drwxrwxrwx 3 Iwao users 4.0K Jul 29 18:16 ./ drwxrwxrwx 5 Iwao users 4.0K Jul 29 15:31 ../ drwxrwxrwx 2 Iwao users 4.0K Jul 29 18:05 bak/ -rwxrwxrwx 1 Iwao users 188 Jul 29 16:29 hello.c* -rw-r--r-- 1 Iwao users 1.6K Jul 29 16:33 hello.o -rwxrwxrwx 1 Iwao users 910 Jul 29 16:32 helloWrap.BAK* -rwxrwxrwx 1 Iwao users 936 Jul 29 16:37 helloWrap.c* -rw-r--r-- 1 Iwao users 3.1K Jul 29 18:16 helloWrap.o -rwxr-xr-x 1 Iwao users 8.3K Jul 29 18:16 hellomodule.so* Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello $ python3 Python 3.7.0 (default, Aug 23 2018, 17:48:39) [GCC 4.6.4] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import hello Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'hello' >>> exit() Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello $ python Python 2.7.10 (default, Aug 19 2015, 09:18:54) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import hello Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: dynamic module does not define init function (inithello) >>> exit() Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/hello $
まだ何か違うみたい.
メッセージは inithello がないとなっているので helloWrap.c を見直すと…
void initchello() { … } となっている.
関数名を inithello に変更してビルドすると通った.
2020/07/30
今日は次の所を参考にさせてもらって…
https://cpp-learning.com/python_c_api_step1/
Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/py_hello $ gcc ph_hello.c -o mymodule.so -fPIC -Wall -shared -I /volume1/.@plugins/AppCentral/python3/include/python3.7m/ Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/py_hello $ python3 Python 3.7.0 (default, Aug 23 2018, 17:48:39) [GCC 4.6.4] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import mymodule Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: dynamic module does not define module export function (PyInit_mymodule) >>> import myModule Traceback (most recent call last): File "<stdin>", line 1, in <module> ModuleNotFoundError: No module named 'myModule' >>> Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/py_hello $ cp mymodule.so myModule.so Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/py_hello $ ll total 44 drwxrwxrwx 3 Iwao users 4.0K Jul 30 16:49 ./ drwxrwxrwx 6 Iwao users 4.0K Jul 30 14:59 ../ drwxrwxrwx 2 Iwao users 4.0K Jul 30 16:48 bak/ -rwxr-xr-x 1 Iwao users 8.1K Jul 30 16:49 myModule.so* -rwxr-xr-x 1 Iwao users 8.1K Jul 30 16:47 mymodule.so* -rwxrwxrwx 1 Iwao users 188 Jul 29 16:29 ph_hello.BAK* -rwxrwxrwx 1 Iwao users 1.3K Jul 30 16:27 ph_hello.c* Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/py_hello $ python3 Python 3.7.0 (default, Aug 23 2018, 17:48:39) [GCC 4.6.4] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import myModule >>> myModule.helloworld <built-in function helloworld> >>> myModule.helloworld() Hello World >>> >>> >>> >>> Iwao@AS5202T:/volume1/home/Iwao/test/test_py/call_c/py_hello $
コンパイル時の出力ファイル名 mymodule.so が間違っていた.正しくは myModule.so .
そこ には詳しく書かれているが,自分用にメモ.
PyMethodDef の “メソッド名” は Python 側での (モジュール名).(メソッド名) .
同様に PyModuleDef の “モジュール名” は import 時の名称..so の出力ファイル名も対応している必要がある?
文字列なので,異なっていてもコンパイル時のエラーにはならない.
実行時に見つからないなどのエラーとなる.
2020/07/31
続きの内容をやっていて…
https://cpp-learning.com/python_c_api_step2/
Fatal Python error: GC object already tracked
c_list は Python 側で確保しているため Py_DECREF はうまくないのではないか?