views:

157

answers:

3

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.

+3  A: 

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);
Nick Craig-Wood
+4  A: 
/* 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);
Alex Martelli
A: 

Most functions in pygame module are just wrappers around SDL functions, that is where you have to look for C version of its functions. pygame.h defines a series of import_pygame_*() functions. Call import_pygame_base() and others once at initialization of extension module to get access to needed part of C API of pygame modules (it's defined in header file for each). Google code search will bring you some examples.

Denis Otkidach