问题
I am making my first venture into integrating C and Python 2.7.3. For starters, I'm just trying to write a C module for Python that can do basic addition. (It is called npfind because once I figure this out, I want to write a find method for numpy)
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"])])
After all that, on Windows 7, I type
python npfindsetup.py build_ext --inplace --compiler=mingw32
Which seems to work. When I then try to find npfind.py, I get this error:
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
I cannot figure out what it is talking about. What are METH_CLASS and METH_STATIC, and why I am I trying to set them?
回答1:
You are declaring the _npfindmethods
as a pointer, and trying to initialize it as an array. When I build a code copied from your snippets, I get a lot of warnings like:
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]
(...)
The variable is initialized with an incorrect value, and thus Python finds random data inside.
You should declare _npfindmethods
as an array instead:
static PyMethodDef _npfindmethods[] = {
{"add", py_add, METH_VARARGS, py_add_doc},
{NULL, NULL, 0, NULL}
};
Now it will be initialized as you expect it to. Also, because now py_add_doc
needs to have constant address, you have to make it an array as well:
static char py_add_doc[] = "Adds two numbers.";
So, your final pynpfind.c
would look like:
#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);
}
来源:https://stackoverflow.com/questions/11584765/integrating-c-and-python-valueerror-module-functions-cannot-set-meth-class-or