简体   繁体   English

对Python进行C扩展,需要另一个扩展

[英]Making a C extension to Python that requires another extension

I have a couple of Python functions that I use to make game development with Pygame easier. 我有几个Python函数,我用它来使Pygame的游戏开发更容易。 I have them in a file called helper.py in my Python-path, so I can import them from any game I make. 我把它们放在我的Python路径中名为helper.py的文件中,所以我可以从我制作的任何游戏中导入它们。 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. 我想,作为一个学习Python扩展的练习,将这个模块转换为C.我的第一个问题是我需要使用Pygame中的函数,我不确定这是否可行。 Pygame installs some header files, but they don't seem to have C versions of the Python functions. Pygame安装了一些头文件,但它们似乎没有C函数的Python版本。 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. 顺便说一句,使用Windows XP,Python 2.6和Pygame 1.9.1。

/* 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);

You can import python modules from C code and call things defined in just like you can in python code. 你可以从C代码中导入python模块,并像在python代码中一样调用定义的东西。 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 . 当我想弄清楚如何做这样的事情时,我会看一下C API文档 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. 但是我怀疑你真正想做的是从C调用底层库sdl 。这是一个C库,从C开始很容易使用。

Here is some sample code to import a python module in C adapted from a bit of working code 下面是一些示例代码,用于在C中导入python模块,该代码是从一些工作代码改编而来的

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);

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模块中的大多数函数只是围绕SDL函数的包装器,在这里你必须查找其函数的C版本。 pygame.h defines a series of import_pygame_*() functions. pygame.h定义了一系列import_pygame_*()函数。 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). 在初始化扩展模块时调用import_pygame_base()和其他一次,以访问pygame模块的所需C API部分(在每个头文件中定义)。 Google code search will bring you some examples . Google代码搜索会为您带来一些示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM