problem using C-bindings

Scott David Daniels Scott.Daniels at Acm.Org
Sun Aug 22 20:29:21 EDT 2004


eq wrote:
> Am Thu, 19 Aug 2004 17:45:45 -0400 schrieb Jack Diederich:
> 
> 
>>On Thu, Aug 19, 2004 at 10:32:15PM +0200, eq wrote:
>>
>>>Hi,
>>>
>>>I'm trying to create a program(written in C) that does the following
>>>things using embedded Python:
>>>1. Create a module(say, "MyModule")
>>>2. Create a class in that module(say, "MyClass")
>>>3. Create a function in that module(say, "MyFunction")
>>
>>[snip]
>>
>>>	class_dict=PyDict_New();
>>>	class_name=PyString_FromString("MyClass");
>>>	class=PyClass_New(NULL,class_dict,class_name);
>>>	PyDict_SetItemString(module_dict,"MyClass",class);
>>
>>[snip]
>>
>>Take a look at Modules/xxsubtype.c in the source distribution.
>>It is an example of how to subtype a builtin.  xxmodule.c shows
>>how to make a class from scratch.  Both are out of date but a good
>>sarting spot.
>>
> 
> Hm, perhaps I over-complicated my problem:
> I don't need a full python-class in pure C. I just need to create a
> (python!) function(a dynamic one, not a static C function) and attach it
> to an already existing python-class just by using C-calls.
You've already managed this.  The error message is telling you it has
no place to put "self".

> I try to do this by compiling the function's code with:
> 
> pyfunc_code=Py_CompileString(func_code,"",Py_file_input);
> 
> where func_code could be something like "print 'hello'" and then I try to
> make a function out of this by calling:
> 
> pyfunc=PyFunction_New(pyfunc_code,dict);
> 
> where dict is the global namespace for the function.
> What I now want is to attach this function to the already created class
> "MyClass".
You should call "staticmethod" on your pyfunc before putting it into the
class.


The error message you got before:
	TypeError: ?() takes no arguments (1 given)
indicates that you had defined a 0-arg function and were calling it
with one arg.  That arg was the "self" arg.  You could do the moral
equivalent of:
     MyClass.MyFunction = staticmethod(MyClass.MyFunction)
after the code you have now.  Alternatively you could pull staticmethod
from __builtins__ and "apply" it yourself before storing in attachFunc.

Just guessing from "funcobject.h", but I'll bet you could also change 
attachFunc as follows

void attachFunc(PyObject* class, PyObject* dict,
                 char* func_code, char* name)
{
	PyObject* pyfunc_code;
	PyObject* pyfunc;
	pyfunc_code=Py_CompileString(func_code,"",Py_file_input);
	pyfunc=PyFunction_New(pyfunc_code,dict);
	pyfunc=PyStaticMethod_New(pyfunc);

	PyObject_SetAttrString(class,name,pyfunc);
}

You do know you need to do much more error checkig here, don't you?
Untested (my mail machine and my C machine are different).

int attachFunc(PyObject* class, PyObject* dict,
                char* func_code, char* name)
{
     PyObject* pyfunc_code = NULL;
     PyObject* pyfunc = NULL;
     PyObject* pyfunc_static = NULL;
     int result = -1; /* 0 for success */

     pyfunc_code = Py_CompileString(func_code, "", Py_file_input);
     if (pyfunc_code) {
         pyfunc = PyFunction_New(pyfunc_code, dict);
         if (pyfunc) {
             pyfunc_static = PyStaticMethod_New(pyfunc);
             result = PyObject_SetAttrString(class, name, pyfunc);
         }
     Py_XDECREF(pyfunc_static);
     Py_XDECREF(pyfunc);
     Py_XDECREF(pyfunc_code);
     return result;
}

-Scott David Daniels
Scott.Daniels at Acm.Org



More information about the Python-list mailing list