Archives for: June 2005, 12
06/12/05
Using Python objects in Python-C interop
As I wrote in my previous article, I did not know yet how to handle Python objects, and call their member functions.
After getting some help from Adam "adamh" Hooper, it became clear this is actually very easy to do.
Here's some code (I'm not reposting the whole C file, just append this to the end, it should be clear):
g_debug("Calling pytest::test using the helper function");
PyObject_CallMethod(ret, "test", NULL);
Py_XDECREF(ret);
ret = NULL;
g_debug("Calling pytest::test, no helper function");
g_debug("Creating a new pytest object");
ret = PyInstance_New(PyDict_GetItemString(dict, "" MODULE_NAME), NULL, NULL);
g_assert(ret != NULL);
PyObject_CallMethod(ret, "test", NULL);
Py_XDECREF(ret);
Watch out: you should not Py_XDECREF(ret) before doing this, of course.
As you can see there are 2 ways to achieve our goal:
- In the first part of the snipper, we use "ret". This is the return value of the global function called "test", which is a "pytest" instance (the "test" function ends with
return pytest()
). We just call PyObject_CallMethod(object, name, args) to call the function. - In the first "solution" we use some ugly hack to get a pytest instance. In the second part we use a cleaner method, by calling PyInstance_New(type, constructor_args, kw). As you can see, we get "type" in the same way we got the entry point to the global "test" function. Now again we can just call a method on the object as in the first part.
This should be the output now:
** (process:13267): DEBUG: Initializing Python ** (process:13267): DEBUG: Setting PATH ** (process:13267): DEBUG: Trying to import "pytest" ** (process:13267): DEBUG: Success loading global test function In main test function, argument is "testarg" Initializing a pytest object ** (process:13267): DEBUG: Calling pytest::test using the helper function In pytest's test function ** (process:13267): DEBUG: Calling pytest::test, no helper function ** (process:13267): DEBUG: Creating a new pytest object Initializing a pytest object In pytest's test function
Looks like Python/C interop is not that hard actually :-) You can find the final code here.