Using a python module's C API in my own C module
This seems to be sort of what I want, except I want to make an instance of a C PyObject in another C module.
Create instance of a python class , declared in python, with C API
But I am not able to find the documentation for using a Python module from C. I can't seem to find the relevent docs online as everyone just talks about extending Python with C.
My issue is that I have a Pygame which I want to speed 开发者_运维技巧up. So I am making a C module which needs access to Pygame. How do I import pygame? I don't want to import two copies, right? The coding part I can figure out, I just don't know how to configure and link the code. I know I must be missing some docs, so if anyone can point me in the right direction, I'd be much obliged.
Update: Sorry I reread my post and realized my wording was terrible.
If you have pygame installed you can look in your Python/include directory and find pygame header files. What are they for? I thought that your C module could access the pygame C module directly, so that your python script AND your C module used the same pygame instance.
Clarification anyone?
The trick is to write the normal Python routine, but in C. Use PyImport_ImportModule()
, PyObject_GetAttr()
, and PyObject_Call()
as appropriate.
You can use the pygame C-API, even though it is probably not meant to be used in that way (which then again begs the question why the pygame headers are installed with the pygame package).
An extension built against such an "internal" API is likely to break when the next version/build of pygame comes out, unless pygame developers care about the API/ABI compatibility of these C headers...
Anyway, here is an example:
C extension module code (red.c):
#include <Python.h>
#include <pygame/pygame.h>
static PyObject* fill_surface(PyObject* self, PyObject* args)
{
PyObject* py_surface = NULL;
if( !PyArg_ParseTuple(args, "O", &py_surface) )
return NULL;
PySurfaceObject* c_surface = (PySurfaceObject*) py_surface;
SDL_FillRect( c_surface->surf, 0, SDL_MapRGB(c_surface->surf->format, 255, 0, 0) );
return Py_None;
}
PyMethodDef methods[] = {
{"fill_surface", fill_surface, METH_VARARGS, "Paints surface red"},
{NULL, NULL, 0, NULL},
};
void initred()
{
Py_InitModule("red", methods);
}
Makefile for building (Linux):
SOURCES = red.c
OBJECTS = $(SOURCES:.c=.o)
TARGET = red.so
CFLAGS += -Wall -O2 -g
CFLAGS += $(shell python-config --cflags)
CFLAGS += $(shell sdl-config --cflags)
LDFLAGS += $(shell sdl-config --libs)
all: $(TARGET)
clean:
$(RM) $(OBJECTS)
$(RM) $(TARGET)
$(TARGET): $(OBJECTS)
$(CC) -shared -o $@ $(OBJECTS) $(LDFLAGS)
$(OBJECTS): Makefile
Python test code:
import pygame
import red
pygame.init()
screen = pygame.display.set_mode( (640, 480) )
red.fill_surface(screen)
pygame.display.update()
pygame.time.delay(3000)
I googled it in a single "I'm feeling lucky."
精彩评论