Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a C extension to Python that requires another extension

Tags:

python

c

pygame

I have a couple of Python functions that I use to make game development with Pygame easier. I have them in a file called helper.py in my Python-path, so I can import them from any game I make. I thought, as an exercise to learn about Python extensions, to convert this module to C. My first problem is that I need to use functions from Pygame, and I'm not sure if this is possible. Pygame installs some header files, but they don't seem to have C versions of the Python functions. Maybe I'm missing something.

How can I solve this? As a workaround, the function currently accepts a function parameter and calls that, but it's not the ideal solution.

Using Windows XP, Python 2.6 and Pygame 1.9.1, by the way.

like image 722
Javier Avatar asked Oct 17 '09 20:10

Javier


2 Answers

/* get the sys.modules dictionary */
PyObject* sysmodules PyImport_GetModuleDict();
PyObject* pygame_module;
if(PyMapping_HasKeyString(sysmodules, "pygame")) {
    pygame_module = PyMapping_GetItemString(sysmodules, "pygame");
} else {
    PyObject* initresult;
    pygame_module = PyImport_ImportModule("pygame");
    if(!pygame_module) {
      /* insert error handling here! and exit this function */
    }
    initresult = PyObject_CallMethod(pygame_module, "init", NULL);
    if(!initresult) {
      /* more error handling &c */
    }
    Py_DECREF(initresult);
}
/* use PyObject_CallMethod(pygame_module, ...) to your heart's contents */
/* and lastly, when done, don't forget, before you exit, to: */
Py_DECREF(pygame_module);
like image 92
Alex Martelli Avatar answered Oct 05 '22 08:10

Alex Martelli


You can import python modules from C code and call things defined in just like you can in python code. It is a bit long winded, but perfectly possible.

When I want to work out how to do something like this I look at the C API documentation. The section on importing modules will help. You'll also need to read how to read attributes, call functions etc which is all in the docs.

However I suspect what you really want to do is call the underlying library sdl from C. This is a C library and is really easy to use from C.

Here is some sample code to import a python module in C adapted from a bit of working code

PyObject *module = 0;
PyObject *result = 0;
PyObject *module_dict = 0;
PyObject *func = 0;

module = PyImport_ImportModule((char *)"pygame"); /* new ref */
if (module == 0)
{
    PyErr_Print();
    log("Couldn't find python module pygame");
    goto out;
}
module_dict = PyModule_GetDict(module); /* borrowed */
if (module_dict == 0)
{
    PyErr_Print();
    log("Couldn't find read python module pygame");
    goto out;
}
func = PyDict_GetItemString(module_dict, "pygame_function"); /* borrowed */
if (func == 0)
{
    PyErr_Print();
    log("Couldn't find pygame.pygame_function");
    goto out;
}
result = PyEval_CallObject(func, NULL); /* new ref */
if (result == 0)
{
    PyErr_Print();
    log("Couldn't run pygame.pygame_function");
    goto out;
}
/* do stuff with result */
out:;
Py_XDECREF(result);
Py_XDECREF(module);
like image 37
Nick Craig-Wood Avatar answered Oct 05 '22 07:10

Nick Craig-Wood