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.
CodePudding user response:
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
:
- arguments consist of two tuples
- each tuple has two integers inside
- first integer in the first tuple maps to
start.x
, second - tostart.y
- first integer in the first tuple maps to
end.x
, second - toend.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, thusstart
andend
are allocated on stack and aren't pointers."(ii)(ii)" tells to look for two tuples (
(...)` means tuple), each consisting of two integers.- we give the addresses where the converted integer values should be stored, e.g.
&start.x
.