1

I'm trying to embed python into c to use it for configuration:

If I do it like this:

/******************************************************************************
* 
* Embeding Python Example
*
* To run: 
*   gcc -c test.c -o test.o -I"C:/Python25/include"
*   gcc -o test.exe test.o -L"C:/Python25/libs" -lpython25
*   test.exe
*
******************************************************************************/

#include <Python.h>

int main(int argc, char *argv[])
{
    PyObject *run;
    PyObject *globals = PyDict_New();
    PyObject *locals = PyDict_New();

    Py_Initialize();

    run = PyRun_String("from time import time,ctime\n"
                       "print 'Today is',ctime(time())\n"
                        "test = 5\n"
                        "print test\n", Py_file_input, globals, locals);


    Py_Finalize();
    return 0;
}

I'm getting a runtime error from the the Microsoft VIsual C++ Runtime, with this message:

Exception exceptions.ImportError: '__import__ not found' in 'garbage collection' ignored
Fatal Python error: unexpected exception during garbage collection

What am I doing wrong?

1
  • FYI, Lua is designed more for lightweight embedding and configuration files than Python. Commented Oct 20, 2010 at 9:33

2 Answers 2

2

What you're doing wrong is exactly what I was doing wrong.

You are initializing your own globals dictionary to be empty. This means even things like __import__ are not defined for the current scope.

In your simple example you can replace

run = PyRun_String("from time import time,ctime\n"
                   "print 'Today is',ctime(time())\n"
                    "test = 5\n"
                    "print test\n", Py_file_input, globals, locals);

with

PyRun_SimpleString("from time import time,ctime\n"
                   "print 'Today is',ctime(time())\n"
                   "test = 5\n"
                   "print test\n");

You'll probably want to remove globals and locals entirely, too.

If I find out how to access the default globals dict, I'll add a comment or edit here.

Edit: The implementation of PyRun_SimpleStringFlags (Python 2.7.3) looks like this:

int PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
{
    PyObject *m, *d, *v;
    m = PyImport_AddModule("__main__");
    if (m == NULL)
        return -1;
    d = PyModule_GetDict(m);
    v = PyRun_StringFlags(command, Py_file_input, d, d, flags);
    ...

So to get the default globals dict you would have to import __main__ and get its dictionary. This will contain all the default built-in functions, etc.

Sign up to request clarification or add additional context in comments.

Comments

0

You're creating 2 Python objects before you've initialized the Python engine.

Also, that's silly. There are plenty of JSON parsers for C.

2 Comments

+1. Why do you want to embed a complete scripting language interpreter into your app just to use as a configuration language?
I tried initializing the objects after inintializing the Python engine, but the error still there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.