942,517 Members | Top Members by Rank

Ad:
  • Python Discussion Thread
  • Marked Solved
  • Views: 21852
  • Python RSS
You are currently viewing page 1 of this multi-page discussion thread
Sep 2nd, 2005
0

calling Python function from C/C++

Expand Post »
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:

Python Syntax (Toggle Plain Text)
  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
Python Syntax (Toggle Plain Text)
  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!
Similar Threads
Reputation Points: 55
Solved Threads: 6
Junior Poster
Micko is offline Offline
148 posts
since Aug 2005
Sep 3rd, 2005
0

Re: calling Python function from C/C++

well I manage to figure it out myself. I'm using Bloodshed Dev-cpp
Here's the code:

Python Syntax (Toggle Plain Text)
  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
Python Syntax (Toggle Plain Text)
  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
Reputation Points: 55
Solved Threads: 6
Junior Poster
Micko is offline Offline
148 posts
since Aug 2005
Sep 3rd, 2005
0

Re: calling Python function from C/C++

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.
Moderator
Reputation Points: 1333
Solved Threads: 1403
DaniWeb's Hypocrite
vegaseat is offline Offline
5,789 posts
since Oct 2004
Sep 3rd, 2005
0

Re: calling Python function from C/C++

Quote 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
Reputation Points: 55
Solved Threads: 6
Junior Poster
Micko is offline Offline
148 posts
since Aug 2005
Sep 10th, 2005
0

Re: calling Python function from C/C++

Well, I manage to embed Python eval function in C code.
If anyone is interested let me know to post solution.
Cheers

- Micko
Reputation Points: 55
Solved Threads: 6
Junior Poster
Micko is offline Offline
148 posts
since Aug 2005
Sep 10th, 2005
0

Re: calling Python function from C/C++

Super job Micko! Why don't you post it right here, or better even in the Python snippetts.
Reputation Points: 404
Solved Threads: 180
Nearly a Posting Virtuoso
bumsfeld is offline Offline
1,422 posts
since Jul 2005
Sep 12th, 2005
0

Re: calling Python function from C/C++

It looks like Boost.Python might be what you are looking for, check out this site:
http://www.boost.org/libs/python/doc/
Moderator
Reputation Points: 1333
Solved Threads: 1403
DaniWeb's Hypocrite
vegaseat is offline Offline
5,789 posts
since Oct 2004
Sep 25th, 2005
0

Re: calling Python function from C/C++

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!
Moderator
Reputation Points: 1333
Solved Threads: 1403
DaniWeb's Hypocrite
vegaseat is offline Offline
5,789 posts
since Oct 2004
Sep 27th, 2005
0

Re: calling Python function from C/C++

Thanks I have forgotten to paste my solution
Here it is:

C file:
Python Syntax (Toggle Plain Text)
  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:

Python Syntax (Toggle Plain Text)
  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++
Reputation Points: 55
Solved Threads: 6
Junior Poster
Micko is offline Offline
148 posts
since Aug 2005
Dec 9th, 2008
0

Re: calling Python function from C/C++

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
Reputation Points: 10
Solved Threads: 1
Newbie Poster
hunkaboy2003 is offline Offline
2 posts
since Dec 2008

This thread is solved

Either the thread starter or a moderator has marked this thread as solved. You can most likely trust the responses and answers given. There is most likely no reason for any further responses to be posted here. If you have a related question, please start a new thread in this forum instead.

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in Python Forum Timeline: Reading from a website
Next Thread in Python Forum Timeline: Printing out a dictionary value





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC