Sign in to follow this  
Pepper_

Embedding Python into a C++application

Recommended Posts

Pepper_    122
Hello! I am trying to embed Python into my C++ application. After some simple testing I decided it would be good to have a PythonManager-class, so I wrote one.
class PythonManager {
public:
	PythonManager(CNetwork *n);
	~PythonManager();
	void privRespond(const std::string &rcvr, const std::string &sndr, const std::string &hst, const std::string &msg);
private:
	std::vector<PyObject *> prvFuncs;
	CNetwork *net;
	std::string out;
	PyObject *pName;
	PyObject *pModule;
	PyObject *pDict;
	PyObject *pFunc;
	PyObject *pValue;
	PyObject *pArgs;
};
In the destructor of this class, I call the Py_Finalize() function. The constructor is responsible for loading all the python-scripts and calling Py_Initialize(). The privRespond()-method will loop through all the registered python-scripts that contains the function "OnPrivMsg()" and pass on the arguments to all of them. This is what it looks like in my test script (base.py)
def OnPrivMsg(receiver, sender, host, message):
	return "PRIVMSG "+receiver+" :Hello "+sender+"!"
This works like a charm. However, when I call Py_Finalize() in the destructor I get an access violation and my app crashes. It is because of something I do wrong in the privRespond-method, because if I comment it out I don't get the access violation. This is what the method looks like:
void PythonManager::privRespond(const std::string &rcvr, const std::string &sndr, const std::string &hst, const std::string &msg) {
	for ( int i=0; i<prvFuncs.size(); i++ ) {
		pArgs = PyTuple_New(4);

		pValue = PyString_FromString(rcvr.c_str());
		PyTuple_SetItem(pArgs, 0, pValue);

		pValue = PyString_FromString(sndr.c_str());
		PyTuple_SetItem(pArgs, 1, pValue);
		
		pValue = PyString_FromString(hst.c_str());
		PyTuple_SetItem(pArgs, 2, pValue);
		
		pValue = PyString_FromString(msg.c_str());
		PyTuple_SetItem(pArgs, 3, pValue);		

		pValue = PyObject_CallObject(prvFuncs[i], pArgs);
		Py_DECREF(pArgs);

		out = PyString_AsString(pValue);
		Py_DECREF(pValue);
		out += "\r\n";
		net->Send(out);
	}
}
Now, my guess is it has something to do with reference counts, but I don't get it, even after reading every article I could find using google. I will post the destructor code also:
PythonManager::~PythonManager() {
	// Clean up
	Py_DECREF(pModule);

	// Shutdown the python interpreter
	Py_Finalize();
}
Thanks in advance!

Share this post


Link to post
Share on other sites
SiCrane    11839
I don't see anything immediately wrong with your code (which admittedly doesn't mean much). Have considered using boost::python to manage your reference counts instead?

Share this post


Link to post
Share on other sites
Pepper_    122
Yeah I looked at it briefly, but decided to try without it. Anyway, I think I'm gonna use it now anyway, since I ran into this much trouble. I just thought I'd ask here first.

Anyway, thanks for your reply!

Regards,
Anton

Share this post


Link to post
Share on other sites
Pepper_    122
I have a new problem. This python code works:

count = 4

def OnJoin(receiver, sender, host, message):
return "PRIVMSG "+receiver+" :Joincount is "+str(count)+" (base.py)"

And this

count = 4

def OnJoin(receiver, sender, host, message):
count = 7 # NEW
return "PRIVMSG "+receiver+" :Joincount is "+str(count)+" (base.py)"

However, this doesn't:

count = 4

def OnJoin(receiver, sender, host, message):
count += 1 # NEW
return "PRIVMSG "+receiver+" :Joincount is "+str(count)+" (base.py)"

Why doesn't that work? When in the python console or in "IDLE" it works... The host c++ app stalls and crashes when this python function is called.

Edit:
I'm done with python now... I think it sucks. I will instead use the mighty language of Pawn (http://www.compuphase.com/pawn/pawn.htm) You should try it too!

[Edited by - Pepper_ on October 8, 2005 9:28:00 PM]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this