LoginSignup
13

More than 5 years have passed since last update.

CでPython3のモジュールを追加してみた

Last updated at Posted at 2017-01-21

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?

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13