1
/* Copyright (C) 2009 Canonical Ltd
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
#ifndef _IMPORT_C_API_H_
19
#define _IMPORT_C_API_H_
22
* Helper functions to eliminate some of the boilerplate when importing a C API
23
* from a CPython extension module.
25
* For more information see _export_c_api.h
28
static const char *_C_API_NAME = "_C_API";
31
* Import a function from the _C_API_NAME dict that is part of module.
33
* @param module The Python module we are importing from
34
* the attribute _C_API_NAME will be used as a dictionary
35
* containing the function pointer we are looking for.
36
* @param funcname Name of the function we want to import
37
* @param func A pointer to the function handle where we will store the
39
* @param signature The C signature of the function. This is validated
40
* against the signature stored in the C api, to make sure
41
* there is no versioning skew.
43
static int _import_function(PyObject *module, const char *funcname,
44
void **func, const char *signature)
47
PyObject *c_obj = NULL;
48
const char *desc = NULL;
50
/* (char *) because Python2.4 defines this as (char *) rather than
53
d = PyObject_GetAttrString(module, (char *)_C_API_NAME);
55
// PyObject_GetAttrString sets an appropriate exception
58
c_obj = PyDict_GetItemString(d, funcname);
60
// PyDict_GetItemString does not set an exception
61
PyErr_Format(PyExc_AttributeError,
62
"Module %s did not export a function named %s\n",
63
PyModule_GetName(module), funcname);
66
desc = (char *)PyCObject_GetDesc(c_obj);
67
if (!desc || strcmp(desc, signature) != 0) {
71
PyErr_Format(PyExc_TypeError,
72
"C function %s.%s has wrong signature (expected %s, got %s)",
73
PyModule_GetName(module), funcname, signature, desc);
76
*func = PyCObject_AsVoidPtr(c_obj);
86
* Get a pointer to an exported PyTypeObject.
88
* @param module The Python module we are importing from
89
* @param class_name Attribute of the module that should reference the
90
* Type object. Note that a PyTypeObject is the python
91
* description of the type, not the raw C structure.
92
* @return A Pointer to the requested type object. On error NULL will be
93
* returned and an exception will be set.
96
_import_type(PyObject *module, const char *class_name)
98
PyObject *type = NULL;
100
type = PyObject_GetAttrString(module, (char *)class_name);
104
if (!PyType_Check(type)) {
105
PyErr_Format(PyExc_TypeError,
106
"%s.%s is not a type object",
107
PyModule_GetName(module), class_name);
110
return (PyTypeObject *)type;
117
struct function_description
121
const char *signature;
124
struct type_description
127
PyTypeObject **pointer;
131
* Helper for importing several functions and types in a data-driven manner.
133
* @param module The name of the module we will be importing
134
* @param functions A list of function_description objects, describing the
135
* functions being imported.
136
* The list should be terminated with {NULL} to indicate
137
* there are no more functions to import.
138
* @param types A list of type_description objects describing type
139
* objects that we want to import. The list should be
140
* terminated with {NULL} to indicate there are no more
142
* @return 0 on success, -1 on error and an exception should be set.
146
_import_extension_module(const char *module_name,
147
struct function_description *functions,
148
struct type_description *types)
150
PyObject *module = NULL;
151
struct function_description *cur_func;
152
struct type_description *cur_type;
155
module = PyImport_ImportModule((char *)module_name);
158
if (functions != NULL) {
159
cur_func = functions;
160
while (cur_func->name != NULL) {
161
ret_code = _import_function(module, cur_func->name,
163
cur_func->signature);
170
PyTypeObject *type_p = NULL;
172
while (cur_type->name != NULL) {
173
type_p = _import_type(module, cur_type->name);
176
*(cur_type->pointer) = type_p;
189
#endif // _IMPORT_C_API_H_