Using a dictionary to pass data to/from embedded python functions

wardm wardm66 at gmail.com
Sat Aug 12 18:54:46 EDT 2006


Thanks Alex for your help, (and advice on focusing the point of my 
question).

I was able to compile and run your example OK, but when I try to use the 
"VarDictionary" in the
MyScriptModule.py code, I get an exception.

I  added the following code to the C app just to add two entries to the 
Dictionary

 PyDict_SetItemString( m_pVarDictionary, "tk1", 
Py_BuildValue("s","test1Val"));
 PyDict_SetItemString( m_pVarDictionary, "tk2", 
Py_BuildValue("s","test2Val"));

Then tried various things in the Python code to display the contents of the 
"VarDictionary",
such as adding the "print VarDictionary" below.

import InterfaceModule

def functionName():
    print "hello"
    print dir(InterfaceModule)
    print "that's all"
 print VarDictionary
    return

Even though "VarDictionary " is in the Dir, every time I try to use the 
"VarDictionary" the program fails.
Am I doing something wrong when I try and reference "VarDictionary" in 
Python ?
I need to be able to get/set entries in VarDictionary from the Python 
function.


"Alex Martelli" <aleax at mac.com> wrote in message 
news:1hjy7rx.1sxrihq1jtyy68N%aleax at mac.com...
> wardm <wardm66 at gmail.com> wrote:
>
>> I have created a Dict object in a C++ App that calls (embedded) Python
>> functions.
>  [[snip snip]]
>> This python code throws an exception when it attempts to access the
>> "VarDictionary".
>> Does anyone know why this fails ?
>
> It fails due to some code of yours that you have not included: in other
> words, the minimal application which embeds Python using _only_ the code
> you show us does not exhibit the failure.
>
> I wrote the following file za.c:
>
> #include "Python.h"
> #include "stdio.h"
> #include "stdlib.h"
>
> int main()
> {
>    printf("start\n");
>    putenv("PYTHONPATH=.");
>    Py_Initialize();
>    printf("inited\n");
>    PyObject* m_pVarDictionary = PyDict_New();
>    printf("dict is %p\n", m_pVarDictionary);
>    PyObject* m_pInterfaceModule =
> PyImport_AddModule("InterfaceModule");
>    printf("modu is %p\n", m_pInterfaceModule);
>    int status = PyModule_AddObject(m_pInterfaceModule, "VarDictionary"
> ,
>                                    m_pVarDictionary);
>    printf("stat is %d\n", status);
>    PyObject* m_pScriptModule = PyImport_ImportModule("MyScriptModule");
>    printf("impo is %p\n", m_pScriptModule);
>
>    PyObject* func = PyObject_GetAttrString(m_pScriptModule,
> "functionName");
>    printf("func is %p\n", func);
>    if (func && PyCallable_Check(func)) {
>       PyObject* ret = PyObject_CallObject(func, NULL);
>       printf("retu is %p\n", ret);
>    }
>    printf("done\n");
>    return 0;
> }
>
> and the following file MyScriptModule.py:
>
> import InterfaceModule
>
> def functionName():
>    print "hello"
>    print dir(InterfaceModule)
>    print "that's all"
>    return
>
> and proceeded to compile and execute as follows: [[Note: it does not
> matter that I'm using 2.5, the code is just as fine with previous
> versions -- it just happens that 2.5 is what I'm using right now in
> order to help out with 2.5's beta testing]]:
>
> brain:~/pyex alex$ gcc -c za.c -I/usr/local/include/python2.5
> brain:~/pyex alex$ gcc -o za za.o -L/usr/local/lib/python2.5/config/
> -lpython2.5
> brain:~/pyex alex$ ./za
>
> and observed exactly the kind of output I predicted [[Note: the exact
> addresses printed of course do not matter]]:
>
> start
> inited
> dict is 0x51c780
> modu is 0x520230
> stat is 0
> impo is 0x5202d0
> func is 0x513770
> hello
> ['VarDictionary', '__doc__', '__name__']
> that's all
> retu is 0xe57c0
> done
> brain:~/pyex alex$
>
> As you see, in particular, VarDictionary is right up there in
> InterfaceModule's dir.
>
>
> There's a well-known essay by Eric Raymond, "How to ask questions the
> smart way", at <http://catb.org/~esr/faqs/smart-questions.html> -- it
> seems to me that you, quite commendably, follow most of Eric's advice,
> but it's still worth reading -- the key point by which you could help us
> to help you is what Eric mentions as "If you have a large, complicated
> test case that is breaking a program, try to trim it and make it as
> small as possible".
>
> In this case, you should try to trim your code down to the smallest
> program using this approach, which you believe should work in a certain
> way but actually doesn't.  The exact code you posted plus the minimal
> additions to make it a compilable program does work the way you appear
> to desire, as I show above; therefore, there must be something else in
> your code that is breaking things.  Do tiny steps of addition and
> restructuring to move this minimal skeleton towards the direction of
> your bigger program (that does not behave this way) until you've found
> exactly the "largest" version that still succeeds, and the minisculely
> larger "smallest" version that fails -- the tiny difference between the
> two must then be the root of the problem, and if the reason is not clear
> at that point then posting here again is exactly the right thing to do.
>
> Perhaps you're falling afoul of the fact that (as documented e.g. at
> <http://docs.python.org/api/moduleObjects.html>) PyModule_AddObject is a
> "convenience function" that steals a reference to the value -- so you
> end up with just one reference to the dictionary object, and if for some
> reason you decref it, the object gets garbage collected.  But, that's
> just a wild guess on my part, since you have not shown us any code
> performing (for example) any decrefs.
>
>
> Alex 





More information about the Python-list mailing list