[Tutor] Re: embedding python in C --- big porblem
Michael P. Reilly
arcege@shore.net
Wed, 15 Sep 1999 11:19:19 -0400 (EDT)
> edward wrote:
>
> > Please mail me your response to ed_tsang@yahoo.com
> > thanks
> >
> > edward wrote:
> >
> > > Hi to all knowlegable python user out there:
> > > I'm am very new to python and have been having huge trouble in embdding
> > > python with c and extending python with c.
> > > here is what I am trying to do:
> > > 1) extending python in c
> > > A)
> > > * create a function mymath(int a, int b) in a file called mymath.c;
If you have a specific C function, then you can easily create a C
wrapper function for it. You can do this with sig, or write the C
wrapper yourself. In fact many of the standard C extension modules are
such wrappers. The function would look like:
PyObject * /* return a Python object */
pyfunc_mymath(self, args)
PyObject *self, *args;
{ PyObject *result;
int rc, a, b;
if (!PyArg_ParseTuple(args, "ii:mymath", &a, &b))
/* PyArg_ParseTuple sets the exception for you */
return NULL;
/* call your function */
rc = mymath(a, b);
/* construct a Python object from it */
result = Py_BuildValue("i", rc);
/* return the resulting Python object */
return result;
}
Now you just need to add the new wrapper function to the module listing
as described in the manuals:
http://www.python.org/doc/current/ext/ext.html
You will need to create a new module to hold this new function (and
possibly others).
> > > * try to call mymath function to add 1 & 2 from a pythohn script,
Import the module created above and call the function:
>>> import mymod
>>> print mymod.mymath(1, 2)
3
> > > * without recompling try to call mymath to add 3 and 4 from the
> > > python script
Call the function with other arguments within Python.
>>> import mymod
>>> mymod.mymath(1, 2)
3
>>> mymod.mymath(3, 4)
7
> > > * without recompliing try to redefine mymath, so that I am
> > > subtracting this time
Well, you can not redefine the internal function of mymath - that is a
C function compiled into the module. But the module IS a normal Python
namespace and namespaces can be changed:
>>> import mymod
>>> mymod.mymath(1, 2)
3
>>> mymod.mymath = lambda a, b: a - b
>>> mymod.mymath(3, 4)
-1
The name is redefined to be a Python lambda function instead of a
builtin C function.
> > > * try to call mymath function to subtract 1 from 2
> > > * without recompliing try to call mymath to subtract 3 from 4
> > > B)
> > > * create a structure which has two elements a and b,
> > > a function initStruct(x,y) to in a file called intiStruct.c.
> > > initStruct(x,y) will initlize a to x, b to y value.
> > > * try from a pythohn script, try to call the initStruct to
> > > intialise the stucture to 2 and 3
This is the same as above.
> > > * without recompling try to call initStruct to intialise structure
> > > to 3 and 4 from the python script
> > > 2) embedding python to c
> > > A)
> > > * create a function mymath(int a, int b) in a file called mymath.py
> > > ;
Creating a C function inside a Python module file?
Assuming you mean to create a Python function, then you can use:
fp = fopen("commands.py", "r");
PyRun_SimpleFile(fp, "commands.py");
This is about the same as `exec("commands.py")'.
Assuming that you mean to call a C function, you would need to code
this into the C program. This is the same as above, except through the
C API instead of through a Python script:
/* import the module */
mymod = PyImport_ImportModule("mymod");
/* get the mymod.initStruct */
myfunc = PyObject_GetAttrString(mymod, "initStruct");
/* call it */
x = 2;
result = PyObject_CallFunction(myfunc, "ii", x, 3);
> > > * try to call mymath function to add 1 & 2 from a C program,
> > > * without recompling try to call mymath to add 3 and 4 from the C
> > > program
That would need to be a C solution and not something for Python to
handle. E.g. reading from stdin, reading from file, reading from UI
form.
> > > * without recompliing try to redefine mymath, so that I am
> > > subtracting this time.
See the first section; again, we're talking about namespaces. But you
have to write code to tell the program to redefine the name "mymath".
> > > * try to call mymath function to subtract 1 from 2, from the C
> > > program
> > > * without recompliing try to call mymath to subtract 3 from 4, from
> > > the C program
Most everything in this section means changing the C program, which
means recompiling, or changing the Python script file.
> > > Can any one help me on this please. Can you give me the complete working
> > > code on this matter. I really need all you expert help on this thing.
> > > thanks.
Considering there is little to go on, it's unlikely that you will get
"complete working code" from anyone. Maybe you could repost what you
are looking to do in a more clearly defined manner.
> I have forgotten to ask one more question on this:
> Is it possible to compile the code such that the resultant will be just one
> excutable? (ie. python executable and the c exxcutable are residing in the
> same process)?
When you extend or embed Python with C (or another language), then you
get one executable (and possibly some dynamic loadables (.so, .dll,
etc. depending on how you build it)
> If that is the case, I suspect I cannot change the input parameters on the fly
> (ie: I cannot do something like having mymath doing addin and then redefining
> the do substraction. without recmpling as in my questions below) Am I right on
> that?
> Thanks a gain
This would depend on what you have the program do. You could have the
program define all of Python if you realllllly wanted (not that I would
suggest it). The python interpreter, like just about any interpreter,
is just read-eval-print loop. Your program could read input parameters
from any medium and use them within the program without recompiling (if
you designed the program to do that.)
I suggest you read the Python documentation thoroughly; specifically:
http://www.python.org/doc/current/ext/ext.html, and
http://www.python.org/doc/current/api/api.html, and possibly even
http://starship.python.net/crew/arcege/extwriting/pyext.html.
-Arcege
--
------------------------------------------------------------------------
| Michael P. Reilly, Release Engineer | Email: arcege@shore.net |
| Salem, Mass. USA 01970 | |
------------------------------------------------------------------------