calling Python function from C/C++

Please support our Python advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved

Join Date: Aug 2005
Posts: 148
Reputation: Micko is on a distinguished road 
Solved Threads: 6
Micko Micko is offline Offline
Junior Poster

calling Python function from C/C++

 
0
  #1
Sep 2nd, 2005
Hello,
I'm writing a simple calculator in C. The main problem is I need to parse string to evaluate for example 1+2*(3-1)/2.5.
However writing such parses is a very hard task.

This is a trivial thing Python using this code:

  1. s = raw_input('Please enter expression:')
  2. try:
  3. x = eval(s)
  4. except NameError:
  5. print 'Unknown elements in the expression!'
  6. except ZeroDivisionError:
  7. print 'Division with zero attempted!'
  8. except:
  9. print 'Some other kind of error!'
  10. else:
  11. print 'Expression is evaluated correctly'

I saw that Python has C API so I assume that Python functions can be called from C.

Is it possible to use Python function eval() to evaluate user string in C program? In other words is it possible to make wrapper to this Python code and evaluate expression in C?
I tried to find answer in Python manual but I'm a complete jackass beginer.

For example I have Test.c
  1. #include <stdio.h>
  2.  
  3. char buff[BUFSIZ];
  4.  
  5. int main(void)
  6. {
  7. char * p;
  8. double res;/* to store result of expression evaluation*/
  9.  
  10. printf ("Please enter expression: ");
  11. fgets(buff, sizeof buff, stdin);
  12. if (p = strrchr(buff,'\n'))
  13. {
  14. *p = '\0';
  15. }
  16.  
  17. /* now wrapper to python function eval()-....? */
  18. }

and from that c file I'd like to call eval and if success to store result to variable res.

I'm using MSCV++ .NET with Win XP and I assume I'll need to use some kind of Python libraray...
There is explanation in Pythion doc, but there is no complete testing source file and my english is not very good to understand all the described steps.
Is this possible at all?

Please, can you help me?

Thanks in advance!
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 148
Reputation: Micko is on a distinguished road 
Solved Threads: 6
Micko Micko is offline Offline
Junior Poster

Re: calling Python function from C/C++

 
0
  #2
Sep 3rd, 2005
well I manage to figure it out myself. I'm using Bloodshed Dev-cpp
Here's the code:

  1. #include "python.h"
  2. #include <stdio.h>
  3.  
  4. int main(int argc, char* argv[])
  5. {
  6. double answer = 0;
  7. PyObject *modname, *mod, *mdict, *func, *stringarg, *args, *rslt;
  8.  
  9. Py_Initialize();
  10. modname = PyString_FromString("Test");
  11. mod = PyImport_Import(modname);
  12. if (mod)
  13. {
  14. mdict = PyModule_GetDict(mod);
  15. func = PyDict_GetItemString(mdict, "doit"); /* borrowed reference */
  16. if (func)
  17. {
  18. if (PyCallable_Check(func))
  19. {
  20. stringarg = PyString_FromString("5");/*pay attention here*/
  21. args = PyTuple_New(1);
  22. PyTuple_SetItem(args, 0, stringarg);
  23. rslt = PyObject_CallObject(func, args);
  24. if (rslt)
  25. {
  26. answer = PyFloat_AsDouble(rslt);
  27. Py_XDECREF(rslt);
  28. }
  29. Py_XDECREF(stringarg);
  30. Py_XDECREF(args);
  31. }
  32. }
  33.  
  34. Py_XDECREF(mod);
  35. }
  36.  
  37. Py_XDECREF(modname);
  38.  
  39. Py_Finalize();
  40.  
  41. printf("%g",answer);
  42.  
  43. return 0;
  44. }
I need to add include and lib directories to the project in order to everything works fine. Also Test.py is copied in Dev-cpp source code's folder.
Test file contains the following code
  1. def doit(x1):
  2. try:
  3. x2 = eval(x1)
  4. except:
  5. print 'Error!'
  6. return 0
  7.  
  8. else:
  9. return x2

However there is an error. Look at the line stringarg = PyString_FromString("5"); If I put this:
stringarg = PyString_FromString("5+2"); or even this stringarg = PyString_FromString("5.0");
Program crashes at line Py_Finalize(). Program tries to read some memory location and suffer run time exception.
Only suggestion is to try to send it to Microsoft.
Why is this happening?
Everything (seems to) works fine I comment line Py_Finalize(), but I know that this is not a real solution.

Does anybode have a clue what is happening?

Thanks
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 4,047
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 935
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite

Re: calling Python function from C/C++

 
0
  #3
Sep 3rd, 2005
A little twist here, the Python24.dll contains all the PyEval routines and they are most likely written in C. So I wonder, if you couldn't access them directly from the dll in your C/C++ program.
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 148
Reputation: Micko is on a distinguished road 
Solved Threads: 6
Micko Micko is offline Offline
Junior Poster

Re: calling Python function from C/C++

 
0
  #4
Sep 3rd, 2005
Originally Posted by vegaseat
A little twist here, the Python24.dll contains all the PyEval routines and they are most likely written in C. So I wonder, if you couldn't access them directly from the dll in your C/C++ program.
I really don't know what you mean. Are you asking me if I had problems with linking library (in MSVC++ I had) python24.lib or what?

And also, can you help me to figure out why I'm getting that nasty send to Microsoft window and why my program read memory which is not supposed to?

Thank you
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 148
Reputation: Micko is on a distinguished road 
Solved Threads: 6
Micko Micko is offline Offline
Junior Poster

Re: calling Python function from C/C++

 
0
  #5
Sep 10th, 2005
Well, I manage to embed Python eval function in C code.
If anyone is interested let me know to post solution.
Cheers

- Micko
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: calling Python function from C/C++

 
0
  #6
Sep 10th, 2005
Super job Micko! Why don't you post it right here, or better even in the Python snippetts.
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 4,047
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 935
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite

Re: calling Python function from C/C++

 
0
  #7
Sep 12th, 2005
It looks like Boost.Python might be what you are looking for, check out this site:
http://www.boost.org/libs/python/doc/
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Join Date: Oct 2004
Posts: 4,047
Reputation: vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice vegaseat is just really nice 
Solved Threads: 935
Moderator
vegaseat's Avatar
vegaseat vegaseat is offline Offline
DaniWeb's Hypocrite

Re: calling Python function from C/C++

 
0
  #8
Sep 25th, 2005
If you have Dev-C++, embedding Python is quite easy with the free Python Development Pak. Look at this C++ code snippet for more information:
http://www.daniweb.com/code/snippet387.html

For the masochists, this might be one way to create an executable Python file. Come to think of it, you could let a Python program do the nasty detailed work!
May 'the Google' be with you!
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 148
Reputation: Micko is on a distinguished road 
Solved Threads: 6
Micko Micko is offline Offline
Junior Poster

Re: calling Python function from C/C++

 
0
  #9
Sep 27th, 2005
Thanks I have forgotten to paste my solution
Here it is:

C file:
  1. #ifdef _DEBUG
  2. #undef _DEBUG
  3. #include "python.h"
  4. #define _DEBUG
  5. #else
  6. #include "python.h"
  7. #endif
  8.  
  9. #include "python.h"
  10. #include <stdio.h>
  11.  
  12. int main (int argc, char* argv[])
  13. {
  14.  
  15. double answer = 0.0;
  16. char buff [BUFSIZ];
  17. char * p;
  18. int test = 0;
  19.  
  20. PyObject *modname, *mod, *mdict, *func, *stringarg, *args, *rslt;
  21.  
  22. fputs ("Enter expression: ",stdout);
  23. fgets (buff, sizeof buff, stdin);
  24.  
  25. if (p = strrchr (buff, '\n'))
  26. {
  27. *p = '\0';
  28. }
  29.  
  30. Py_Initialize();
  31. modname = PyString_FromString ("Test");
  32. if (modname == NULL)
  33. {
  34. Py_Exit(0);
  35. return 0;
  36. }
  37. mod = PyImport_Import (modname);
  38. if (mod)
  39. {
  40. mdict = PyModule_GetDict (mod);
  41. func = PyDict_GetItemString (mdict, "izracunaj");
  42. if (func)
  43. {
  44. if (PyCallable_Check (func))
  45. {
  46. stringarg = PyString_FromString (buff);
  47. args = PyTuple_New (1);
  48. PyTuple_SetItem (args, 0, stringarg);
  49. rslt = PyObject_CallObject (func, args);
  50. if (rslt)
  51. {
  52. if (PyFloat_Check(rslt))
  53. {
  54. answer = PyFloat_AsDouble(rslt);
  55. test = 1;
  56. }
  57. else if (PyInt_Check(rslt))
  58. {
  59. answer = PyInt_AsLong(rslt);
  60. test = 1;
  61. }
  62. else
  63. {
  64. printf ("Nije korektan izraz!\n");
  65. }
  66. Py_XDECREF(rslt);
  67. }
  68.  
  69. Py_XDECREF(args);
  70. }
  71.  
  72. }
  73. else
  74. {
  75. printf("Kivla");
  76. }
  77. Py_XDECREF(mod);
  78. }
  79. else
  80. {
  81. printf("Python module mora biti u istom direkoriju!\n");
  82. PyErr_Print();
  83. }
  84.  
  85. Py_XDECREF(modname);
  86.  
  87. if (test)
  88. {
  89. printf("Izracunat je %g\n",answer);
  90. }
  91.  
  92. return 0;
  93. }

Python file:

  1. from math import *
  2. from __future__ import division
  3. def izracunaj():
  4. x = raw_input ('Enter expression:')
  5. try:
  6. y = eval(x)
  7. except NameError:
  8. print 'Wrong expression'
  9. except:
  10. print 'error in evalution'
  11.  
  12. else:
  13. print '%g' % y

I used MSVC++ .net v2002
i set project path to include folder in Python directory and also includede path for libraries and that was it. I placed Python file in the same project folder in MSVC++
Reply With Quote Quick reply to this message  
Join Date: Dec 2008
Posts: 2
Reputation: hunkaboy2003 is an unknown quantity at this point 
Solved Threads: 1
hunkaboy2003 hunkaboy2003 is offline Offline
Newbie Poster

Re: calling Python function from C/C++

 
0
  #10
Dec 9th, 2008
Hi can you help me im new in python; i tried to call python functions inside c++ and i copied your sample source code and put it in my created function. I comment out the Py_Initialize() and Py_Finalize() because they are called in different part of the program.

I put a break point in the function but the problem is when the game reads the line: func = PyDict_GetItemString(mdict, "PnlPackSel"); it returns NULL.

Any help will be appreciated


C++ Source code:

int GC_PythonCalls()
{

double answer = 0;
PyObject *modname, *mod, *mdict, *func, *stringarg, *args, *rslt;

// Py_Initialize();
modname = PyString_FromString("Menu");
mod = PyImport_Import(modname);
if (mod)
{

mdict = PyModule_GetDict(mod);
func = PyDict_GetItemString(mdict, "PnlPackSel"); /* borrowed reference */
if (func)
{
if (PyCallable_Check(func))
{

rslt = PyObject_CallObject(func, NULL);
if (rslt)
{
//answer = PyFloat_AsDouble(rslt);
Py_XDECREF(rslt);
OutputDebugString("PY CALL SUCCESS \n");
}
Py_XDECREF(stringarg);
Py_XDECREF(args);
}
}

Py_XDECREF(mod);
}

Py_XDECREF(modname);

//Py_Finalize();



return 0;
}


Python Code


def PnlPackSel(self):
App.CtrlMouseSet(100,100)
Pnl = self.PCtrlTopGet();
#bring
self.PCtrlAdd(
self.__class__.AddLvl,
(self, Pnl.ulPackId, False),
True,
);
Thanks in advance
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:



Similar Threads
Other Threads in the Python Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC