Re: C function in a Python context
> #include > #include This modification required: compilercommand='c:/programs/mingw/bin/g++' and strctypes= { 'i': 'int', 's': 'const char*', 'O': 'PyObject*' } The output is: #include [ 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 #include 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 ); } }
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
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