开发者

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."

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜