So I'm trying to create a C extension and am having a bit of trouble accessing the struct data for one of my arguments. Here's my current code:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <numpy/arrayobject.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct Point {
int x;
int y;
} Point;
static PyObject *test(PyObject *self, PyObject *args) {
Point *start, *end = NULL;
if(!PyArg_ParseTuple(args, "OO", &start, &end)) {
return NULL;
}
printf("%d %d\n", (int)start->x, (int)start->y);
printf("%d %d\n", (int)end->x, (int)end->y);
return PyLong_FromLong(0);
}
Python code which calls it:
import testmodule
testmodule.test((5, 4), (7, 1))
I'm trying to get these inputs tuples to be converted into Point
structs so they can be used further on in the program. Any idea how I can fix this?
Any help would be appreciated.
You expect too much from PyArg_ParseTuple
: its implementation knows nothing about the Point
-struct which is defined by you - it has no idea how a tuple can be converted to a Point
struct.
You have to provide the following information to PyArg_ParseTuple
:
start.x
, second - to start.y
end.x
, second - to end.y
This all can be achieved with the following code:
static PyObject *test(PyObject *args) {
Point start, end;
if(!PyArg_ParseTuple(args, "(ii)(ii)", &start.x, &start.y,
&end.x, &end.y)) {
return NULL;
}
printf("%d %d\n", start.x, start.y);
printf("%d %d\n", end.x, end.y);
return PyLong_FromLong(0);
}
"""
As you can see:
PyArg_ParseTuple
will not allocate memory it writes values to existing memory, thus start
and end
are allocated on stack and aren't pointers."(ii)(ii)" tells to look for two tuples (
(...)` means tuple), each consisting of two integers.&start.x
.