[C++-sig] Converting CString to/from std::string

Ralf W. Grosse-Kunstleve rwgk at yahoo.com
Tue May 27 20:42:42 CEST 2003


--- Kirsebom Nikolai <nikolai.kirsebom at siemens.no> wrote:
> Some time ago I made a 'socket based' system (using BISON/FLEX for parsing)
> where I expose C++ objects to python.  In this system CStrings are regular
> Python strings.

Attached is a small, self-contained demo extension module that shows how to do
what you want. Here is the corresponding trivial regression test:

from sandbx_boost import custom_string
assert custom_string.hello() == "Hello world."
assert custom_string.size("california") == 10

If you look at the code you will find:

1. A custom to_python converter (easy): custom_string_to_python_str

2. A custom lvalue converter (needs more code): custom_string_from_python_str

The custom converters are registered in the global Boost.Python registry near
the top of the module initialization function. Once flow control has passed
through the registration code the automatic conversions from and to Python
strings will work in any module imported in the same process.

HTH,
        Ralf

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python/to_python_converter.hpp>

namespace sandbx { namespace {

  class custom_string
  {
    public:
      custom_string() {}
      custom_string(std::string const& value) : value_(value) {}
      std::string const& value() const { return value_; }
    private:
      std::string value_;
  };

  struct custom_string_to_python_str
  {
    static PyObject* convert(custom_string const& s)
    {
      return boost::python::incref(boost::python::object(s.value()).ptr());
    }
  };

  struct custom_string_from_python_str
  {
    custom_string_from_python_str()
    {
      boost::python::converter::registry::push_back(
        &convertible,
        &construct,
        boost::python::type_id<custom_string>());
    }

    static void* convertible(PyObject* obj_ptr)
    {
      if (!PyString_Check(obj_ptr)) return 0;
      return obj_ptr;
    }

    static void construct(
      PyObject* obj_ptr,
      boost::python::converter::rvalue_from_python_stage1_data* data)
    {
      const char* value = PyString_AsString(obj_ptr);
      if (value == 0) boost::python::throw_error_already_set();
      void* storage = (
        (boost::python::converter::rvalue_from_python_storage<custom_string>*)
          data)->storage.bytes;
      new (storage) custom_string(value);
      data->convertible = storage;
    }
  };

  custom_string hello() { return custom_string("Hello world."); }

  std::size_t size(custom_string const& s) { return s.value().size(); }

  void init_module()
  {
    using namespace boost::python;

    boost::python::to_python_converter<
      custom_string,
      custom_string_to_python_str>();

    custom_string_from_python_str();

    def("hello", hello);
    def("size", size);
  }

}} // namespace sandbx::<anonymous>

BOOST_PYTHON_MODULE(custom_string)
{
  sandbx::init_module();
}


__________________________________
Do you Yahoo!?
The New Yahoo! Search - Faster. Easier. Bingo.
http://search.yahoo.com




More information about the Cplusplus-sig mailing list