Re: C function in a Python context
#include string #include vector This modification required: compilercommand='c:/programs/mingw/bin/g++' and strctypes= { 'i': 'int', 's': 'const char*', 'O': 'PyObject*' } The output is: #include c:/programs/python/include/Python.h [ user code ] static PyObject * extcode_enumfactors(PyObject *self, PyObject *args) { PyObject* result; int arg0; const char* arg1; PyArg_ParseTuple(args, is, arg0, arg1 ); result= enumfactors( arg0, arg1 ); return Py_BuildValue( O, result ); } static PyMethodDef ExtcodeMethods[] = { { enumfactors, extcode_enumfactors, METH_VARARGS, }, {NULL, NULL, 0, NULL} }; PyMODINIT_FUNC initextcode(void) { (void) Py_InitModule(extcode, ExtcodeMethods); } The benefits are automatic parameter parsing and automatic method table construction. The costs are portability and parameter parsing flexibility. Add up. -- http://mail.python.org/mailman/listinfo/python-list
Re: C function in a Python context
On Feb 9, 3:04 pm, [EMAIL PROTECTED] wrote: On Feb 9, 1:48 pm, [EMAIL PROTECTED] wrote: To write quick C things that Python won't do up to speed. So it's got a redundancy. import ext extA= ext.Ext() extA[ 'enumfactors' ]= r int enumfactors( int a, const char* sep ) { int ret= 0, i; for( i= 1; i= a; i++ ) { if( a% i== 0 ) { ret+= 1; if( i 1 ) { printf( %s, sep ); } printf( %i, i ); } } printf( \n ); return ret; } , (i,i,s) factorsn= extA.enumfactors( 209677683, ', ' ) print( %i factors total.% factorsn ) import sys sys.exit() 1, 3, 23, 69, 131, 393, 3013, 9039, 23197, 69591, 533531, 1600593, 3038807, 9116 421, 69892561, 209677683 16 factors total. '''Prototype implementation, slightly rigid. If anyone knows how to compile and link without intermediate object file, and from a string, memory, or stdin, let me know. Change first four lines. If you are not using gcc, look at regenpyd().''' compilercommand= 'c:/programs/mingw/bin/gcc' pythondll= 'python30' pythonpathinclude= 'c:/programs/python/include' pythonpathlibs= 'c:/programs/python/libs' class Ext: strctypes= { 'i': 'int', 's': 'const char*' } class ExtElem: def __init__( self, name, code, types ): self.name, self.code= name, code self.types= types def __init__( self ): self.__dict__[ 'exts' ]= [] def regenc( self ): extcode= open( 'extcode.c', 'w' ) wr= extcode.write wr( '#include %s'% pythonpathinclude ) wr( '/Python.h\n\n' ) for ext in self.exts: wr( ext.code ) wr( '\n' ) for ext in self.exts: wr( 'static PyObject *\n' ) wr( 'extcode_%s'% ext.name ) wr( '(PyObject *self, ' ) wr( 'PyObject *args) {\n' ) wr( '\t%s result;\n'% Ext.strctypes[ext.types[0]] ) for i, type in enumerate( ext.types[1:] ): wr( '\t%s arg%i;\n'% ( Ext.strctypes[type], i ) ) wr( '\tPyArg_ParseTuple(args, ' ) wr( ''.join( ext.types[1:] ) ) wr( '' ) for i, type in enumerate( ext.types[1:] ): wr( ', arg%i'% i ) wr( ' );\n' ) wr( '\tresult= %s( '% ext.name ) wr( ', '.join( [ 'arg%i'% i for i in range( len( ext.types[1:] ) ) ] ) ) wr( ' );\n' ) wr( '\treturn Py_BuildValue' ) wr( '( %s, result );\n'% ext.types[0] ) wr( '}\n\n' ) wr( 'static PyMethodDef ExtcodeMethods[] = {\n' ) for ext in self.exts: wr( '\t{ %s, extcode_%s, '% ( ext.name, ext.name ) ) wr( 'METH_VARARGS, },\n' ) wr( '\t{NULL, NULL, 0, NULL}\n' ) wr( '};\n\n' ) wr( 'PyMODINIT_FUNC\n' ) wr( 'initextcode(void) {\n' ) wr( '\t(void) Py_InitModule' ) wr( '(extcode, ExtcodeMethods);\n' ) wr( '}\n\n' ) extcode.close() def regenpyd( self ): import os, os.path if os.path.exists( 'extcode.pyd' ): os.remove( 'extcode.pyd' ) import subprocess retcompile= subprocess.call( '%s extcode.c -c -I%s'% ( compilercommand, pythonpathinclude ) ) assert not retcompile, 'Compiler error' retlink= subprocess.call( '%s -shared extcode.o -o extcode.pyd -L%s -l%s' % ( compilercommand, pythonpathlibs, pythondll ) ) assert not retlink, 'Linker error' os.remove( 'extcode.o' ) os.remove( 'extcode.c' ) def __setitem__( self, key, value ): code, types= value self.exts.append( Ext.ExtElem( key, code, types ) ) self.regenc() self.regenpyd() import extcode setattr( self, key, getattr( extcode, key ) )- Hide quoted text - - Show quoted text - This is- and returns a list, of the enumerated factors. Is it starting to get bulky. import ext extA= ext.Ext() extA[ 'enumfactors' ]= r #include string #include vector using namespace std; PyObject* enumfactors( int a, const char* sep ) { string fmt= [; vector long resv; for( int i= 1; i= a; i++ ) { if( a% i== 0 ) { resv.push_back( i ); fmt.append( i ); if( i 1 ) { printf( %s, sep ); } printf( %i, i ); } } printf( \n ); fmt.append( ] ); PyObject* res= PyList_New( resv.size() ); for( int i= 0; i resv.size(); i++ ) { PyObject* v= PyLong_FromLong( resv[i] );
C function in a Python context
To write quick C things that Python won't do up to speed. So it's got a redundancy. import ext extA= ext.Ext() extA[ 'enumfactors' ]= r int enumfactors( int a, const char* sep ) { int ret= 0, i; for( i= 1; i= a; i++ ) { if( a% i== 0 ) { ret+= 1; if( i 1 ) { printf( %s, sep ); } printf( %i, i ); } } printf( \n ); return ret; } , (i,i,s) factorsn= extA.enumfactors( 209677683, ', ' ) print( %i factors total.% factorsn ) import sys sys.exit() 1, 3, 23, 69, 131, 393, 3013, 9039, 23197, 69591, 533531, 1600593, 3038807, 9116 421, 69892561, 209677683 16 factors total. -- http://mail.python.org/mailman/listinfo/python-list
Re: C function in a Python context
On Feb 9, 1:48 pm, [EMAIL PROTECTED] wrote: To write quick C things that Python won't do up to speed. So it's got a redundancy. import ext extA= ext.Ext() extA[ 'enumfactors' ]= r int enumfactors( int a, const char* sep ) { int ret= 0, i; for( i= 1; i= a; i++ ) { if( a% i== 0 ) { ret+= 1; if( i 1 ) { printf( %s, sep ); } printf( %i, i ); } } printf( \n ); return ret; } , (i,i,s) factorsn= extA.enumfactors( 209677683, ', ' ) print( %i factors total.% factorsn ) import sys sys.exit() 1, 3, 23, 69, 131, 393, 3013, 9039, 23197, 69591, 533531, 1600593, 3038807, 9116 421, 69892561, 209677683 16 factors total. '''Prototype implementation, slightly rigid. If anyone knows how to compile and link without intermediate object file, and from a string, memory, or stdin, let me know. Change first four lines. If you are not using gcc, look at regenpyd().''' compilercommand='c:/programs/mingw/bin/gcc' pythondll= 'python30' pythonpathinclude= 'c:/programs/python/include' pythonpathlibs= 'c:/programs/python/libs' class Ext: strctypes= { 'i': 'int', 's': 'const char*' } class ExtElem: def __init__( self, name, code, types ): self.name, self.code= name, code self.types= types def __init__( self ): self.__dict__[ 'exts' ]= [] def regenc( self ): extcode= open( 'extcode.c', 'w' ) wr= extcode.write wr( '#include %s'% pythonpathinclude ) wr( '/Python.h\n\n' ) for ext in self.exts: wr( ext.code ) wr( '\n' ) for ext in self.exts: wr( 'static PyObject *\n' ) wr( 'extcode_%s'% ext.name ) wr( '(PyObject *self, ' ) wr( 'PyObject *args) {\n' ) wr( '\t%s result;\n'% Ext.strctypes[ext.types[0]] ) for i, type in enumerate( ext.types[1:] ): wr( '\t%s arg%i;\n'% ( Ext.strctypes[type], i ) ) wr( '\tPyArg_ParseTuple(args, ' ) wr( ''.join( ext.types[1:] ) ) wr( '' ) for i, type in enumerate( ext.types[1:] ): wr( ', arg%i'% i ) wr( ' );\n' ) wr( '\tresult= %s( '% ext.name ) wr( ', '.join( [ 'arg%i'% i for i in range( len( ext.types[1:] ) ) ] ) ) wr( ' );\n' ) wr( '\treturn Py_BuildValue' ) wr( '( %s, result );\n'% ext.types[0] ) wr( '}\n\n' ) wr( 'static PyMethodDef ExtcodeMethods[] = {\n' ) for ext in self.exts: wr( '\t{ %s, extcode_%s, '% ( ext.name, ext.name ) ) wr( 'METH_VARARGS, },\n' ) wr( '\t{NULL, NULL, 0, NULL}\n' ) wr( '};\n\n' ) wr( 'PyMODINIT_FUNC\n' ) wr( 'initextcode(void) {\n' ) wr( '\t(void) Py_InitModule' ) wr( '(extcode, ExtcodeMethods);\n' ) wr( '}\n\n' ) extcode.close() def regenpyd( self ): import os, os.path if os.path.exists( 'extcode.pyd' ): os.remove( 'extcode.pyd' ) import subprocess retcompile= subprocess.call( '%s extcode.c -c -I%s'% ( compilercommand, pythonpathinclude ) ) assert not retcompile, 'Compiler error' retlink= subprocess.call( '%s -shared extcode.o -o extcode.pyd -L%s -l%s' % ( compilercommand, pythonpathlibs, pythondll ) ) assert not retlink, 'Linker error' os.remove( 'extcode.o' ) os.remove( 'extcode.c' ) def __setitem__( self, key, value ): code, types= value self.exts.append( Ext.ExtElem( key, code, types ) ) self.regenc() self.regenpyd() import extcode setattr( self, key, getattr( extcode, key ) ) -- http://mail.python.org/mailman/listinfo/python-list