/* Reference: Embedded Python 3.0 -------------------------------- I was having a bit of trouble getting embedded Python to work in a project, and it took me a while to figure this out. Hope this code helps if anyone else wants to integrate Python functionality in their C programs, and then expose code to it. This code introduces a module called "lenneth" into an embedded python interpreter (accessed in this case by PyRun_String), and exposes the C function python_test (access this with function1(1) in python). */ #include #include #include /* BEGIN-- DO gcc -o sample.exe py-c.c -lpython30 END-- */ PyObject *python_test(PyObject *self, PyObject *args); PyMODINIT_FUNC PyInit_lenneth(void); PyObject *PyInitializeEnvironment(); // This needs to be updated, an entry for each function to be exposed to the // python interpreter. static PyMethodDef LennethMethods[] = { {"function1", python_test, METH_VARARGS,"python test function #1"}, // {"function2", py_function2, METH_VARARGS,"python test function #2"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; // This struct also needs to be updated, for each function exposed. static void *PyLenneth_API[1] = { (void *)python_test }; static struct PyModuleDef modLenneth = { PyModuleDef_HEAD_INIT, "lenneth", NULL, -1, LennethMethods }; int main(int argc,char **argv) { Py_Initialize(); PyObject *pDict = PyInitializeEnvironment(); PyObject *pyRet; // this can be included as a part of PyInitializeEnvironment. PyRun_String("import sys", Py_file_input, pDict, pDict); PyRun_String("from lenneth import *", Py_file_input, pDict, pDict); pyRet = PyRun_String("function1(1)", Py_file_input, pDict, pDict); if(PyErr_Occurred() != NULL) { PyErr_Print(); } Py_Finalize(); return; } // This function sets up the python initial environment, and allows the // embedded python instance to access the 'lenneth' module. PyObject *PyInitializeEnvironment() { PyObject *m = PyModule_New("lenneth"); PyModule_AddStringConstant(m, "__file__",""); PyImport_AppendInittab("lenneth", PyInit_lenneth); PyImport_ImportModule("lenneth"); PyObject *pDict = PyModule_GetDict(m); PyDict_SetItemString(pDict, "__builtins__", PyEval_GetBuiltins() ); return pDict; } // this function is essentially the initialization of the "lenneth" function. // this function allows us to make use of C api's within lenneth. PyMODINIT_FUNC PyInit_lenneth(void) { PyObject *m; PyObject *c_api_object; m = PyModule_Create(&modLenneth); if (m == NULL) return NULL; c_api_object = PyCObject_FromVoidPtr((void *)PyLenneth_API, NULL); if (c_api_object != NULL) PyModule_AddObject(m, "_C_API", c_api_object); return m; } PyObject *python_test(PyObject *self, PyObject *args) { long bstart; // consult python manuals for data marshalling functions. PyArg_ParseTuple(args,"l",&bstart); if(bstart == 1) { printf("* %s\n",Py_GetVersion()); } return Py_None; }