Cで書いたプログラムをPython3から使えるようにしてみた
参考文献がどれも古くて、Python3に対応させるのに苦労しました、、、
まずはソースコード
hello.c
int add(int x, int y)
{
return x + y;
}
void out(const char* adrs, const char* name)
{
printf("こんにちは、私は %s の %s です。\n", adrs, name);
}
これはCのソースコードで、add,outの二つの関数を持っている
helloWrapper.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}
};
static struct PyModuleDef hellomodule =
{
PyModuleDef_HEAD_INIT,
"hellomodule", /* name of module */
"", /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
hellomethods
};
PyMODINIT_FUNC PyInit_hellomodule(void)
{
return PyModule_Create(&hellomodule);
}
こっちがメインのソースコード。
プログラムのそれぞれの意味はこちら参照
→PythonからCプログラムを呼び出す
実行してみる
コンパイル
3つのコマンドを実行する。
gcc -fpic -o hello.o -c hello.c
gcc -fpic -I`python3-config --prefix`/Headers -o helloWrapper.o -c helloWrapper.c
gcc -L`python3-config --prefix`/lib -lpython3.5 -shared hello.o helloWrapper.o -o hellomodule.so
- まずはhello.cをコンパイルしてオブジェクトファイルを作成
- -Iで
python3-config--prefix
にあるヘッダーファイルを指定してあげてhelloWrapper.cをコンパイルしてあげる - そして最後に-Lで
python3-config--prefix
にあるライブラリの場所を指定してあげて、ライブラリの作成
python3から試す
実際に試してみよう、ほんとにできてるかな?
hnkz $ python3
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 26 2016, 10:47:25)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hellomodule
>>> hellomodule.add(2,3)
5
>>> hellomodule.out("hamamatsu","hnkz")
こんにちは、私は hamamatsu の hnkz です。
できてる!すごい!!
応用してPython3でキーロガーを作りたいな。
参考文献
PythonからCプログラムを呼び出す
PythonでCバインディング試してみた
Compiler can't find Py_InitModule() .. is it deprecated and if so what should I use?