I ran into a situation with pure python and C python module.
To summarize, how can I accept and manipulate python object in C module?
My python part will look like this.
#!/usr/bin/env python
import os, sys
from c_hello import *
class Hello:
busyHello = _sayhello_obj
class Man:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
h = Hello()
h.busyHello( Man("John") )
in C, two things need to be resolved.
first, how can I receive object?
second, how can I call a method from the object?
static PyObject *
_sayhello_obj(PyObject *self, PyObject *args)
{
PyObject *obj;
// How can I fill obj?
char s[1024];
// How can I fill s, from obj.getName() ?
printf("Hello, %s\n", s);
return Py_None;
}
To extract an argument from an invocation of your method, you need to look at the functions documented in Parsing arguments and building values, such as
PyArg_ParseTuple. (That’s for if you’re only taking positional args! There are others for positional-and-keyword args, etc.)The object you get back from
PyArg_ParseTupledoesn’t have it’s reference count increased. For simple C functions, you probably don’t need to worry about this. If you’re interacting with other Python/C functions, or if you’re releasing the global interpreter lock (ie. allowing threading), you need to think very carefully about object ownership.For calling a method on an object, you need to use either
PyObject_CallMethodorPyObject_CallMethodObjArgs, depending on how you construct the argument list and method name. And see my comment in the code about object ownership!Quick digression just to make sure you’re not setting yourself up for a fall later: If you really are just getting the string out to print it, you’re better off just getting the object reference and passing it to
PyObject_Print. Of course, maybe this is just for illustration, or you know better than I do what you want to do with the data 😉Now there are a number of functions in the String/Bytes Objects section of the Concrete Objects Layer docs; use whichever works best for you.
But do not forget this bit:
Note the use of
Py_RETURN_NONEthere, and note that it’s notreturn Py_RETURN_NONE!PS. The structure of this code is dictated to a great extent by personal style (eg. early returns,
static charformat strings inside the function, initialisation toNULL). Hopefully the important information is clear enough apart from stylistic conventions.