2013-12-15 7 views
3

Я нашел этот фрагмент кода с помощью python 2.7.5, который представляет собой главу об экспонировании C-API для других модулей в расширении Python с помощью C и C++: Предоставление C API для расширения МодульКапсулы функции Python

/* C API functions */ 
#define PySpam_System_NUM 0 
#define PySpam_System_RETURN int 
#define PySpam_System_PROTO (const char *command) 
// ... 
static PySpam_System_RETURN PySpam_System PySpam_System_PROTO; 
// ... 
static void **PySpam_API; 

#define PySpam_System \ 
(*(PySpam_System_RETURN (*)PySpam_System_PROTO) PySpam_API[PySpam_System_NUM]) 

Это отрезанное для функциональных капсул. Капсула используется для передачи функций между двумя модулями. Но в чем смысл этого фрагмента: [...] (PySpam_SystemRETURN (*)PySpam_System_PROTO) [...]. Я думаю, что это что-то вроде статического броска. Что-то вроде (int(*)(char s)). Но в чем смысл этой конструкции?

+0

Вы имеете в виду [capsules] (http://docs.python.org/3.1/c-api/capsule.html)? –

+0

Прости, да! Я исправил это. – Sebi2020

ответ

4

Как определено, макрос PySpam_System расширяется в:

(*(int (*)(const char *command)) PySpam_API[0]) 

который в основном обращаются к PySpam_API[0], бросая его в указатель на функцию приема const char * и возвращение int и разыменования этот указатель.

Это эквивалентно записи:

int (*)(const char *command) function_ptr = (int (*)(const char *command)) PySpam_API[0] 
#define PySpam_System (*function_ptr) 

То есть, это равносильно объявлению переменной function_ptr, который является указателем на ту же функцию, на которую указывает PySpam_API[0] отлиты в int (*)(const char *), а затем с помощью PySpam_System как ярлык для разыменования указателя, что означает, что PySpam_System может быть использован, как если бы это была функция, как:

PySpam_System("an example"); 

Это фактически вызывает функцию POIN ted до PySpam_API[0] с аргументом "an example". Обратите внимание, что функция должна быть совместима с литой.

Кроме того, обратите внимание, что код определяет функцию с именем PySpam_System перед определением макроса PySpam_System. Это приводит к тому, что если вы используете PySpam_System() перед #define, вы будете вызывать эту функцию:

static PySpam_System_RETURN PySpam_System PySpam_System_PROTO; 

(который расширяется static int PySpam_System(const char *command);)

Если вы используете PySpam_System() после #define, вы будете называть макрос, который вызывает функцию, на которую указывает PySpam_API[0].