/recipes/C/579110_Add_functiPythons_builtmodule_through_C/recipe-579110.c

https://github.com/ActiveState/code · C · 141 lines · 111 code · 22 blank · 8 comment · 18 complexity · f3ac644a3dc0c1355f60283441001774 MD5 · raw file

  1. #include <stdio.h>
  2. #include <Python.h>
  3. PyObject *pName, *pModule, *pFunc;
  4. PyObject *builtin, *builtinname, *builtin_dict, *myfunc;
  5. /* python mymodule */
  6. static PyObject*
  7. mymodule_usleep(PyObject *self, PyObject *args)
  8. {
  9. unsigned long i;
  10. if (!PyArg_ParseTuple(args, "k:usleep", &i)) {
  11. return NULL;
  12. }
  13. usleep(i);
  14. return Py_None;
  15. }
  16. static char mymodule_usleep_doc[] =
  17. "usleep(unsigned long) - Sleep for the specified number of microseconds.";
  18. static PyMethodDef mymodule_methods[] = {
  19. {"usleep", mymodule_usleep, METH_VARARGS, mymodule_usleep_doc},
  20. {NULL, NULL}
  21. };
  22. /* python mymodule */
  23. int
  24. pyinit(char * pfile)
  25. {
  26. char syspath[255], pwd[255];
  27. char fname[] = "bar";
  28. Py_Initialize();
  29. /* need for add pwd directory */
  30. PyRun_SimpleString("import sys");
  31. strcpy(syspath, "sys.path.append('");
  32. if (getcwd(pwd, sizeof(pwd)) != NULL) {
  33. strcat(syspath, pwd);
  34. }
  35. strcat(syspath, "')");
  36. PyRun_SimpleString(syspath);
  37. /* add new function to __builtin__ module */
  38. // http://stackoverflow.com/questions/6565175/adding-new-command-to-module-through-c-api
  39. // Python3: https://mail.python.org/pipermail/python-list/2015-October/697917.html
  40. pName = PyString_FromString("__builtin__");
  41. builtin = PyImport_Import(pName);
  42. builtinname = PyString_FromString("__builtin__");
  43. builtin_dict = PyModule_GetDict(builtin);
  44. myfunc = PyCFunction_NewEx(&mymodule_methods[0], (PyObject*)NULL, builtinname);
  45. PyDict_SetItemString(builtin_dict, "usleep", myfunc);
  46. Py_DECREF(pName);
  47. /* end of new function adding */
  48. /* load Own python script */
  49. pName = PyString_FromString(pfile);
  50. PyErr_Print();
  51. pModule = PyImport_Import(pName);
  52. Py_DECREF(pName);
  53. if (pModule != NULL) {
  54. pFunc = PyObject_GetAttrString(pModule, fname);
  55. if (pFunc && PyCallable_Check(pFunc)) {
  56. return 0;
  57. }
  58. else {
  59. if (PyErr_Occurred()) {
  60. PyErr_Print();
  61. }
  62. fprintf(stderr, "Cannot find function \"%s\"\n", fname);
  63. Py_XDECREF(pFunc);
  64. Py_XDECREF(pModule);
  65. Py_XDECREF(builtin);
  66. Py_XDECREF(builtinname);
  67. Py_XDECREF(builtin_dict);
  68. Py_XDECREF(myfunc);
  69. return 1;
  70. }
  71. }
  72. else {
  73. PyErr_Print();
  74. fprintf(stderr, "Failed to load \"%s\"\n", pfile);
  75. return 1;
  76. }
  77. return 0;
  78. }
  79. void myloop() {
  80. int rc, var1, var2;
  81. PyObject *mydict, *pArgs, *pValue;
  82. printf("Enter numbers:");
  83. rc = scanf("%d %d", &var1, &var2);
  84. while (rc == 2) {
  85. mydict = Py_BuildValue("{sisi}","a", var1, "b", var2);
  86. pArgs = PyTuple_New(1);
  87. PyTuple_SetItem(pArgs, 0, mydict);
  88. pValue = PyObject_CallObject(pFunc, pArgs);
  89. Py_DECREF(pArgs);
  90. if (pValue != NULL) {
  91. printf("Result of call: %ld\n", PyInt_AsLong(pValue));
  92. Py_DECREF(pValue);
  93. }
  94. else {
  95. PyErr_Print();
  96. fprintf(stderr,"Call failed\n");
  97. }
  98. Py_DECREF(mydict);
  99. printf("Enter numbers: ");
  100. rc = scanf("%d %d", &var1, &var2);
  101. }
  102. }
  103. int main(int argc, char **argv) {
  104. if (argc < 2) {
  105. fprintf(stderr, "Usage: call pythonfile\n");
  106. return 1;
  107. }
  108. if (pyinit(argv[1]) == 0) {
  109. myloop();
  110. Py_DECREF(pFunc);
  111. Py_DECREF(pModule);
  112. Py_DECREF(builtin);
  113. Py_DECREF(builtinname);
  114. Py_DECREF(builtin_dict);
  115. Py_DECREF(myfunc);
  116. }
  117. Py_Finalize();
  118. return 0;
  119. }