See All Titles |
![]() ![]() Code ExamplesListing 6.1 Benchmark Extension (File benchmarkmodule.c)1: #include "<Python.h>" 2: 3: static PyObject * 4: benchmark_generate(PyObject *self, PyObject *args); 5: { 6: int index, number_of_arguments; 7: PyObject *numberslist = NULL; 8: PyObject *check_value = NULL; 9: PyFloatObject *aux_float = NULL; 10: double element_value; 11: double minimum_value = 100; 12: double maximum_value = 0; 13: char *exist_check; 14: 15: if (!PyArg_ParseTuple (args, "OO", &numberslist, &check_value)) 16: return NULL; 17: 18: if (!PyList_Check(numberslist)) 19: { 20: PyErr_SetString(PyExc_TypeError, "Invalid list of values !"); 21: return NULL; 22: } 23: 24: if (!PyFloat_Check(check_value)) 25: { 26: PyErr_SetString(PyExc_TypeError, "Invalid checking value !"); 27: return NULL; 28: } 29: 30: number_of_arguments = PyList_Size(numberslist); 31: exist_check = "No"; 32: 33: for (index=0; index<number_of_arguments; index++) 34: { 35: aux_float = (PyFloatObject *) PyList_GetItem(numberslist, index); 36: if (!PyFloat_Check(aux_float)) 37: { 38: PyErr_SetString(PyExc_TypeError, "Invalid list value !"); 39: return NULL; 40: } 41: element_value = PyFloat_AsDouble(aux_float); 42: if (element_value < 0 ) 43: { 44: PyErr_SetString(PyExc_TypeError, "The values cannot be less than 0 !"); 45: return NULL; 46: } 47: 48: if (element_value > 100 ) 49: { 50: PyErr_SetString(PyExc_TypeError, "The values cannot be greater than 100 !"); 51: return NULL; 52: } 53: 54: if (element_value < minimum_value) 55: minimum_value = element_value; 56: 57: if (element_value > maximum_value) 58: maximum_value = element_value; 59: 60: if (element_value == PyFloat_AsDouble(check_value)) 61: exist_check = "Yes"; 62: } 63: return Py_BuildValue("(ffs)", minimum_value, maximum_value, exist_check ); 64: } 65: 66: static PyMethodDef benchmark_methods[] = { 67: {"generate", benchmark_generate, METH_VARARGS, "Minimum Value, Maximum Value"}, 68: {NULL, NULL} 69: }; 70: 71: DL_EXPORT(void) initbenchmark() 72: { 73: Py_InitModule("benchmark", benchmark_methods); 74: } Line 9: PyFloatObject is a subtype of PyObject. Line 18: Checks whether the first argument is a list. Line 24: Checks whether the type of the second argument is a float. Line 26: Raises a TypeError exception. Line 30: Returns the list's length. Line 60: PyFloat_AsDouble converts a Python Float into a C double. Next, you can see a small interaction with this program. To execute it, we have to pass two arguments: The first one is a list of numbers, and the second one is a float number. This program returns the minimum and maximum values from the list, along with a logical test that informs whether the float number is part of the list. Python 1.5.2 (#0, May 30 2000, 00:16:14) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> import benchmark >>> benchmark.generate([1.1],1.1) (1.1, 1.1, 'Yes') >>> benchmark.generate([1,2,3],4.5) (1.0, 3.0, 'No') >>> Wrapping C FunctionsBy wrapping functions, you can use C code files, without changing them. Every time you feel the need to include a C source code file in your Python project, it is necessary to create a special module that wraps its functions, and to include a reference to the file in the python15.dsp. The next example wraps the functions stored in the cfunctions.c file. Listing 6.2 File: cfunctions.c#include <stdio.h> void display_info(char *user, char *domain, char *country) { if (country == "USA") printf("%s@%s\n", user, domain); else printf("%s@%s.%s\n", user, domain, country); } int calc_year (int f_year, int m_year, int l_year) { int result; result = ((l_year + m_year + f_year) / 3); return result; } Listing 6.3 File: wrappermodule.c1: #include "Python.h" 2: 3: extern void display_info(char *, char *, char *); 4: extern int calc_year(int, int, int); 5: 6: static PyObject *wrapper_display_info(PyObject *self, PyObject *args, PyObject *kwargs) 7: { 8: char *user = "None"; 9: char *domain = "None"; 10: char *country = "None"; 11: static char *keywords[] = {"user","domain","country",NULL}; 12: 13: if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|sss", keywords, &user, &domain, &country)){ 14: return NULL; 15: } 16: 17: display_info(user, domain, country); 18: return Py_BuildValue(""); 19: } 20: 21: static PyObject *wrapper_calc_year(PyObject *self, PyObject *args) { 22: int f_year, m_year, l_year, result; 23: if (!PyArg_ParseTuple(args, "iii", &f_year, &m_year, &l_year)) { 24: return NULL; 25: } 26: result = calc_year(f_year, m_year, l_year); 27: return Py_BuildValue("i", result); 28: } 29: 30: static PyMethodDef wrappermethods[] = { 31: {"display_info", wrapper_display_info, METH_VARARGS|METH_KEYWORDS}, 32: {"calc_year", wrapper_calc_year, METH_VARARGS}, 33: {NULL, NULL} 34: }; 35: 36: void initwrapper() { 37: Py_InitModule("wrapper", wrappermethods); 38: } Lines 3 and 4: Identify which functions are external to this file. Line 11: Creates a dictionary of keywords to be accepted by the function. Line 13: PyArg_ParseTupleAndKeywords() parses the Python-level parameters by accepting a third "PyObject *" parameter. Line 31: The METH_VARARGS|METH_KEYWORDS clause makes it clear that keyword elements are expected. Next, you can see a small interaction with this program. The first function builds an email address based on the information provided. The other one calculates the average age of a family of three people based on the number of years that are passed to the function. Python 1.5.2 (#0, May 30 2000, 00:56:46) [MSC 32 bit (Intel)] on win32 Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam >>> import wrapper >>> wrapper.display_info("andre2530","aol.com","br") andre2530@aol.com.br >>> wrapper.calc_year(10, 30, 35) 25 >>>
|
© 2002, O'Reilly & Associates, Inc. |