[C++-sig] wchar_t* type conversion

Nicolas Lara nicolaslara at gmail.com
Mon Jun 22 19:27:08 CEST 2009


Hi Renato,
Thanks for the reply. Here's some test code. (I pasted it to make it
more friendly =)
http://paste.pocoo.org/show/124521/

Testing it in python: http://paste.pocoo.org/show/124523/

Thanks in advance!
Best Regards

For the archives:

=== test.cpp

#include "CLucene.h"
#include <string>
#include <boost/python.hpp>

using namespace boost::python;

struct wchar_t_to_python_str
{
  static PyObject* convert(wchar_t* const& w)
  {
    string s = "";
    wchar_t* w2 = w;
    while(*w2++ != 0){
      s += *w2;
    }
    return boost::python::incref(boost::python::object(s).ptr());
  }
};

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

  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);
    Py_ssize_t l = PyString_Size(obj_ptr);
    if (value == 0) boost::python::throw_error_already_set();
    void* storage = (

(boost::python::converter::rvalue_from_python_storage<wchar_t*>*)
                     data)->storage.bytes;

    wchar_t* w = new wchar_t[l];
    for(int i=0;i<l;i++){
      w[i] = value[i];
    }
    data->convertible = w;
  }
};

void init_module()
{
  to_python_converter<wchar_t*,wchar_t_to_python_str>();
  wchar_t_from_python_str();
}


struct Test {
  Test(){}

  wchar_t * testReturnValue(string s){
    wchar_t *p=new wchar_t[s.size()];
    for(string::size_type i=0; i<s.size(); ++i)
      p[i]=s[i];
    return p;
  }

  void testArgument(wchar_t * w){
    printf("ok\n");
  }
};


BOOST_PYTHON_MODULE(test){
  init_module();
  class_<Test>("Test")
    //.def("testReturnValue", &Test::testReturnValue) // <- desn't compile
    .def("testArgument", &Test::testArgument);
  ;

}

==== testing it in python
>>> import test

>>> t = test.Test()

>>> t.testArgument(u"")
---------------------------------------------------------------------------
ArgumentError                             Traceback (most recent call last)

/home/.../build/<ipython console> in <module>()

ArgumentError: Python argument types in
    Test.testArgument(Test, unicode)
did not match C++ signature:
    testArgument(Test {lvalue}, wchar_t*)

>>> t.testArgument("")
---------------------------------------------------------------------------
ArgumentError                             Traceback (most recent call last)

/home/.../build/<ipython console> in <module>()

ArgumentError: Python argument types in
    Test.testArgument(Test, str)
did not match C++ signature:
    testArgument(Test {lvalue}, wchar_t*)

>>> from ctypes import c_wchar_p

>>> c_wchar_p("hello")
>>> c_wchar_p(u'hello')

>>> w = c_wchar_p("hello")

>>> t.testArgument(w)
---------------------------------------------------------------------------
ArgumentError                             Traceback (most recent call last)

/home/nicolas/devel/CyLucene/build/<ipython console> in <module>()

ArgumentError: Python argument types in
    Test.testArgument(Test, c_wchar_p)
did not match C++ signature:
    testArgument(Test {lvalue}, wchar_t*)


On Mon, Jun 22, 2009 at 1:48 PM, Renato Araujo<renatox at gmail.com> wrote:
> Hi Nicolas,
>
> Can  you send a simple example, where the convention fail (c++ to
> python or python to c++)? What kind of test you are running?
>
> BR
> Renato
>
>
>
> On Mon, Jun 22, 2009 at 8:31 AM, Nicolas Lara<nicolaslara at gmail.com> wrote:
>> Hello,
>> I'm new to Boost::Python and am encountering a problem that seem to be
>> quite common: I need to expose a class to C++ whose constructor takes
>> a wchar_t* as a parameter.
>> The problem is that there is no default type converter from wchar_t to
>> python and vice-versa.
>>
>> I wanted to know if there was a standard way of doing this. Or if
>> anyone could point me to an implementation of this type conversion.
>>
>> So far I'm doing this (based on the faq):
>>
>> struct wchar_t_to_python_str
>> {
>>  static PyObject* convert(wchar_t* const& w)
>>  {
>>    string s = "";
>>    wchar_t* w2 = w;
>>    while(*w2++ != 0){
>>      s += *w2;
>>    }
>>    return boost::python::incref(boost::python::object(s).ptr());
>>  }
>> };
>>
>> struct wchar_t_from_python_str
>> {
>>  wchar_t_from_python_str()
>>  {
>>    boost::python::converter::registry::push_back(
>>                           &convertible,
>>                           &construct,
>>                           boost::python::type_id<wchar_t>());
>>  }
>>
>>  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);
>>    Py_ssize_t l = PyString_Size(obj_ptr);
>>    if (value == 0) boost::python::throw_error_already_set();
>>    void* storage = (
>>
>> (boost::python::converter::rvalue_from_python_storage<wchar_t*>*)
>>                     data)->storage.bytes;
>>
>>    wchar_t* w = new wchar_t[l];
>>    for(int i=0;i<l;i++){
>>      w[i] = value[i];
>>    }
>>    data->convertible = w;
>>  }
>> };
>>  void init_module()
>>  {
>>    to_python_converter<wchar_t*,wchar_t_to_python_str>();
>>    wchar_t_from_python_str();
>>   }
>>
>> BOOST_PYTHON_MODULE(queryparser){
>>  init_module();
>> }
>>
>> But it doesn't seem to be working. It compiles, but python doesn't
>> understand the conversion.
>> Any thoughts?
>>
>>
>> Thanks in advance!
>>
>> --
>> Nicolas Lara
>> Linux user #380134
>> http://nicolas-lara.blogspot.com/
>> Public key id: 0x152e7713 at http://subkeys.pgp.net/
>> _______________________________________________
>> Cplusplus-sig mailing list
>> Cplusplus-sig at python.org
>> http://mail.python.org/mailman/listinfo/cplusplus-sig
>>
>
>
>
> --
> Renato Araujo Oliveira Filho
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>



-- 
Nicolas Lara
Linux user #380134
http://nicolas-lara.blogspot.com/
Public key id: 0x152e7713 at http://subkeys.pgp.net/


More information about the Cplusplus-sig mailing list