Использование C API модуля Python в моем собственном модуле C - PullRequest
3 голосов
/ 31 января 2010

Это похоже на то, что я хочу, за исключением того, что я хочу сделать экземпляр PyObject C в другом модуле C.

Создание экземпляра класса Python, объявленного в Python, с C API

Но я не могу найти документацию для использования модуля Python из C. Я не могу найти соответствующие документы в Интернете, поскольку все просто говорят о расширении Python с C.

Моя проблема в том, что у меня есть Pygame, которую я хочу ускорить. Поэтому я делаю модуль C, которому нужен доступ к Pygame. Как мне импортировать Pygame? Я не хочу импортировать две копии, верно? Часть кода, которую я могу понять, я просто не знаю, как настроить и связать код. Я знаю, что, должно быть, мне не хватает некоторых документов, поэтому, если кто-нибудь сможет указать мне правильное направление, я буду очень признателен.


Обновление: Извините, я перечитал свой пост и понял, что моя формулировка ужасна.

Если у вас установлен pygame, вы можете заглянуть в каталог Python / include и найти файлы заголовков pygame. Для чего они? Я думал, что ваш модуль C может напрямую обращаться к модулю C Pygame, поэтому ваш скрипт Python И ваш модуль C использовали один и тот же экземпляр Pygame.

Разъяснение кого-нибудь?

Ответы [ 3 ]

1 голос
/ 31 января 2010

Хитрость в том, чтобы написать обычную процедуру Python, но на C. Используйте PyImport_ImportModule(), PyObject_GetAttr() и PyObject_Call() в зависимости от ситуации .

0 голосов
/ 25 апреля 2011

Вы можете использовать C-API pygame, даже если он, вероятно, не предназначен для такого использования (что опять же вызывает вопрос, почему заголовки pygame устанавливаются вместе с пакетом pygame).

Расширение, построенное на основе такого «внутреннего» API, может сломаться, когда выйдет следующая версия / сборка pygame, если разработчики pygame не позаботятся о совместимости API / ABI этих заголовков C ...

В любом случае, вот пример:

Код модуля расширения C (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 для сборки (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:

import pygame
import red

pygame.init()
screen = pygame.display.set_mode( (640, 480) )
red.fill_surface(screen)
pygame.display.update()
pygame.time.delay(3000)
0 голосов
/ 31 января 2010

Я погуглил это за один «Мне повезло».

...