[C++-sig] Passing a reference to my object to python
Lawrence Spector
Lawrence.Spector at CanfieldSci.com
Thu Jul 5 20:18:44 CEST 2007
Ok, I went through and created an example.
Here's what the code looks like, as of right now:
PythonPassReference.cpp:
#include <boost/python.hpp>
#include "TestClass.hpp"
#include "TestClassWrap.hpp"
#include <iostream>
using namespace boost::python;
int main()
{
try
{
Py_Initialize();
object main_module((
handle<>(borrowed(PyImport_AddModule("__main__")))));
object main_namespace = main_module.attr("__dict__");
TestClass testClass(std::cout, 3, 9.6f, 'Q');
{
handle<> ignored((PyRun_String(
"import PythonInterface"
, Py_file_input
, main_namespace.ptr()
, main_namespace.ptr())
));
}
TestClassWrap testClassWrapper(testClass);
boost::python::object pyTestClass(testClassWrapper);
// Works: pyTestClass.attr("output")();
{
handle<> ignored((PyRun_String(
// Works: "pyTestClass = PythonInterface.TestClass(6, 8.3, 'W')\n"
"pyTestClass.output()\n" // Error unless the previous line is uncommented
, Py_file_input
, main_namespace.ptr()
, main_namespace.ptr())
));
}
}
catch(boost::python::error_already_set& e)
{
std::cerr << "Caught error_already_set" << std::endl;
if (PyErr_Occurred() != 0)
{
PyErr_Print();
} // end if
}
catch(...)
{
std::cerr << "Caught unknown error" << std::endl;
} // end try-catch
std::cin.get();
return 0;
} // end main
TestClass.hpp:
#pragma once
#include <iostream>
class TestClass
{
private:
std::ostream& m_outStream;
int m_x;
float m_y;
char m_z;
public:
TestClass(std::ostream& p_outStream, int p_x, float p_y, char p_z) :
m_outStream(p_outStream), m_x(p_x), m_y(p_y), m_z(p_z)
{
} // end TestClass
~TestClass()
{
} // end TestClass
void output()
{
m_outStream << "x = " << m_x << ", y = " << m_y << ", z = " << m_z << "\n";
} // end callMethod
}; // end TestClass
TestClassWrap.hpp:
#pragma once
#include "TestClass.hpp"
class TestClassWrap
{
private:
TestClass m_testClass;
public:
TestClassWrap(const TestClass& p_testClass) :
m_testClass(p_testClass)
{
} // end TestClassWrap
TestClassWrap(int p_x, float p_y, char p_z) :
m_testClass(std::cout, p_x, p_y, p_z)
{
} // end TestClass
~TestClassWrap()
{
} // end TestClass
void output()
{
m_testClass.output();
} // end callMethod
}; // end TestClassWrap
PythonInterface.cpp (Built with BJam, makes PythonInterface.pyd, PythonInterface.lib):
#include <string>
#include <boost/python.hpp>
#include <iostream>
#include "TestClass.hpp"
#include "TestClassWrap.hpp"
using namespace boost::python;
BOOST_PYTHON_MODULE(PythonInterface)
{
class_<TestClassWrap>("TestClass", init<int, float, char>())
.def("output", &TestClassWrap::output)
;
} // end module
In doing so, one issue was illustrated. I was making a wrapper around the class in my interface code to expose to Python. However, when I put it into a boost::python::object, I used the unwrapped class, instead of the wrapped one. Once I started using the wrapped class in my example, the error I was talking about earlier went away, which is good! So I'm past that point.
I ran into a second error, however. As you can see in the example above, I have an object which I wrap and then pass to python as follows:
TestClassWrap testClassWrapper(testClass);
boost::python::object pyTestClass(testClassWrapper);
This works just fine, and I can call methods on the object. However, when I try to run it as a string (as it would be if read from a .py script file), I get an error. Here's the code for that:
{
handle<> ignored((PyRun_String(
"pyTestClass.output()\n" // Error unless the previous line is uncommented
, Py_file_input
, main_namespace.ptr()
, main_namespace.ptr())
));
}
Which produces the following error:
Caught error_already_set
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'pyTestClass' is not defined
So, I guess the question is, how do I expose an instance called pyTestClass, in such a way, that I can call methods on it from a script?
I'm definitely further along now and I appreciate all the help. If I can get this piece, I think I'll be in good shape.
Thanks,
Lawrence
-----Original Message-----
From: c++-sig-bounces at python.org [mailto:c++-sig-bounces at python.org] On Behalf Of Roman Yakovenko
Sent: Thursday, July 05, 2007 12:33 PM
To: Development of Python/C++ integration
Subject: Re: [C++-sig] Passing a reference to my object to python
On 7/5/07, Lawrence Spector <Lawrence.Spector at canfieldsci.com> wrote:
>
> Anyway, I guess I'm stuck and I was wondering if someone might be able to supply or direct me to some working sample code. I'm sure I'm missing an important concept.
Can you create small & complete example which reproduce the error, and
attach the error?
--
Roman Yakovenko
C++ Python language binding
http://www.language-binding.net/
_______________________________________________
C++-sig mailing list
C++-sig at python.org
http://mail.python.org/mailman/listinfo/c++-sig
More information about the Cplusplus-sig
mailing list