2013年1月26日 星期六

embedded python in c code

底下用 PyObject embedded c 的方式,寫了個 python sqlit3 embedded c 的範例.


  • PyObject   : PyList, Pytuple, Py_buildValue, PyCheck , assertion ...
  • standard c : struct


command:
%gcc -lpython2.7 test.c

sample code
#include 
#include 
#include 


struct Sqlite {
    PyObject* sqlite3_ptr;
    PyObject* connect_ptr;
    PyObject* cursor_ptr;
    PyObject* exec_ptr;
    PyObject* commit_ptr;
    PyObject* header_ptr;
    PyObject* body_ptr;
    PyObject* result_ptr;

} Sqlite;

struct Table {
    char* name;
    int   age;
} Table[] = {
    { "john", 18 }
};

/*
 * print macro
 */
void
print_macro(PyObject *self) {
    PyObject* repr_ptr = PyObject_Repr(self);
    const char* repr_s = PyString_AsString(repr_ptr);
    printf("%s\n",repr_s);
}

/*
 * load python modules
 * */
void
load_py_modules()
{
    PyRun_SimpleString("import sqlite3");
    Sqlite.sqlite3_ptr = PyImport_AddModule("sqlite3");
    Py_DECREF(Sqlite.sqlite3_ptr);

#ifdef DEBUG
print_macro(Sqlite.sqlite3_ptr);
#endif
}


/*
 * connect = sqlite3.connect("tt.db")
 * */
void
create_connect(char* dbname)
{

    Sqlite.connect_ptr = PyObject_GetAttrString(Sqlite.sqlite3_ptr,"connect");
    Sqlite.connect_ptr = PyObject_CallFunction(Sqlite.connect_ptr,"s",dbname);
    Py_DECREF(Sqlite.connect_ptr);

#ifdef DEBUG
print_macro(Sqlite.connect_ptr);
#endif
}

/*
 * cursor = connect.cursor()
 * */
void
create_cursor()
{

    Sqlite.cursor_ptr = PyObject_CallMethod(Sqlite.connect_ptr,"cursor",NULL,NULL);
    Py_DECREF(Sqlite.cursor_ptr);

#ifdef DEBUG
print_macro(Sqlite.cursor_ptr);
#endif
}

/*
 * cursor.execute("CREATE TABLE test (name text, age real)"
 * */
void
create_table_header(char* query)
{
    Sqlite.exec_ptr = PyObject_GetAttrString(Sqlite.cursor_ptr,"execute");
    Py_DECREF(Sqlite.exec_ptr);
    Sqlite.header_ptr = PyObject_CallFunction(Sqlite.exec_ptr,"s",query);
    Py_DECREF(Sqlite.header_ptr);

#ifdef DEBUG
print_macro(Sqlite.header_ptr);
#endif
}

/*
 * cursor.execute("INSERT INTO test VALUES ( sean, 28 )
 * */
void
create_table_body(char* query)
{
    Sqlite.exec_ptr = PyObject_GetAttrString(Sqlite.cursor_ptr,"execute");
    Py_DECREF(Sqlite.exec_ptr);
    Sqlite.body_ptr = PyObject_CallFunction(Sqlite.exec_ptr,"s",query);
    Py_DECREF(Sqlite.body_ptr);

#ifdef DEBUG
print_macro(Sqlite.body_ptr);
#endif
}

/*
 * connect.commit()
 * */
void
save_commit()
{
    Sqlite.commit_ptr = PyObject_CallMethod(Sqlite.connect_ptr,"commit",NULL,NULL);
    Py_DECREF(Sqlite.commit_ptr);
}

/*
 *  inspect_table_body
 */
void
inspect_table_body(char* query)
{
    Sqlite.exec_ptr = PyObject_GetAttrString(Sqlite.cursor_ptr,"execute");
    Sqlite.result_ptr = PyObject_CallFunction(Sqlite.exec_ptr,"s",query);

#ifdef DEBUG
print_macro(Sqlite.result_ptr);
#endif
}

/*
 * inspect results
 * */
void
inspect_table_results()
{
    PyObject* item;
    PyObject* val;
    int i;
    char* str;

    Sqlite.result_ptr = PyObject_GetAttrString(Sqlite.cursor_ptr,"fetchone");
    Py_DECREF(Sqlite.result_ptr);

    for (int i=0; i < PyList_Size(Sqlite.result_ptr); i++) {
 item = PyList_GetItem(Sqlite.result_ptr,i);

 for (int j=0; j < PyTuple_Size(item); j++) {
     val = PyTuple_GetItem(item,j);

     if (IntCheck(val)) {
  PyArg_Parse(val,"i",&i);
  printf ("%i, ",i);
     } else {
  PyArg_Parse(val,"z",&str);
  printf ("%s, ",str);
     }
 }
    }
}

/*
 * sqlite.close()
 * */
void
close_connect()
{
    Sqlite.connect_ptr = PyObject_GetAttrString(Sqlite.sqlite3_ptr,"close");

#ifdef DEBUG
print_macro(Sqlite.connect_ptr);
#endif
}


int
main(int argc, char *argv[])
{
    Py_SetProgramName(argv[0]);  /* optional but recommended */

    Py_Initialize();

    load_py_modules();
    create_connect("test.db");
    create_cursor();
    create_table_header("CREATE TABLE test (name text, age real)");
    create_table_body("INSERT INTO test VALUES (john, 18)");
    save_commit();
    inspect_table_body("SELECT * From test");
    inspect_table_results();
    close_connect();
    Py_Finalize();
    return 0;
}

Download
auto stepup tools:

ref:
object protocol

hello world 

沒有留言:

張貼留言