1

私はCとPython2.7.3の統合に最初の冒険をしています。手始めに、基本的な加算を実行できるPython用のCモジュールを作成しようとしています。(これを理解したら、numpyのfindメソッドを作成したいのでnpfindと呼ばれます)

npfind.h:

#include <math.h>

extern int add(int a, int b);

npfind.c:

#include "npfind.h"

int add(int a, int b)
{
    return a + b;
}

pynpfind.c:

#include "Python.h"
#include "npfind.h"

static char* py_add_doc = "Adds two numbers.";
static PyObject* py_add(PyObject* self, PyObject* args)
{
    int a, b, r;

    if (!PyArg_ParseTuple(args, "ii", &a, &b))
    {
        return NULL;
    }

    r = a + b;

    return Py_BuildValue("i", r);
}

static PyMethodDef* _npfindmethods = {
    {"add", py_add, METH_VARARGS, py_add_doc},
    {NULL, NULL, 0, NULL}
};

void init_npfind(void)
{
    PyObject* mod;
    mod = Py_InitModule("_npfind", _npfindmethods);
}

npfind.py:

from _npfind import *

#Do stuff with the methods

npfindsetup.py

from distutils.core import setup, Extension

setup(name="npfind", version="1.0", py_modules = ['npfind.py'],
      ext_modules=[Extension("_npfind", ["pynpfind.c", "npfind.c"])])

結局のところ、Windows7では次のように入力します

python npfindsetup.py build_ext --inplace --compiler=mingw32

これはうまくいくようです。次にnpfind.pyを見つけようとすると、次のエラーが発生します。

Traceback (most recent call last):
  File "npfind.py", line 1, in <module>
    from _npfind import *
ValueError: module functions cannot set METH_CLASS or METH_STATIC

それが何を話しているのか理解できません。METH_CLASSとMETH_STATICとは何ですか、なぜそれらを設定しようとしているのですか?

4

1 に答える 1

3

をポインタとして宣言し_npfindmethods、配列として初期化しようとしています。スニペットからコピーしたコードを作成すると、次のような多くの警告が表示されます。

a.c:24:5: warning: braces around scalar initializer [enabled by default]
a.c:24:5: warning: (near initialization for '_npfindmethods') [enabled by default]
a.c:24:5: warning: initialization from incompatible pointer type [enabled by default]
a.c:24:5: warning: (near initialization for '_npfindmethods') [enabled by default]
(...)

変数が誤った値で初期化されているため、Pythonは内部でランダムなデータを検出します。


_npfindmethods代わりに配列として宣言する必要があります。

static PyMethodDef _npfindmethods[] = {
    {"add", py_add, METH_VARARGS, py_add_doc},
    {NULL, NULL, 0, NULL}
};

これで、期待どおりに初期化されます。また、py_add_doc定数アドレスが必要なため、配列にする必要があります。

static char py_add_doc[] = "Adds two numbers.";

したがって、ファイナルpynpfind.cは次のようになります。

#include "Python.h"
#include "npfind.h"

static char py_add_doc[] = "Adds two numbers.";
static PyObject* py_add(PyObject* self, PyObject* args)
{
    int a, b, r;

    if (!PyArg_ParseTuple(args, "ii", &a, &b))
    {
        return NULL;
    }

    r = a + b;

    return Py_BuildValue("i", r);
}

static PyMethodDef _npfindmethods[] = {
    {"add", py_add, METH_VARARGS, py_add_doc},
    {NULL, NULL, 0, NULL}
};

void init_npfind(void)
{
    PyObject* mod;
    mod = Py_InitModule("_npfind", _npfindmethods);
}
于 2012-07-20T22:26:33.903 に答える