[C++-sig] wchar_t* type conversion

Renato Araujo renatox at gmail.com
Mon Jun 22 20:57:02 CEST 2009


Hi Nicolas

At my first look I get this working changing the register function:

<< to_python_converter<wchar_t*,wchar_t_to_python_str>();
>> to_python_converter<wchar_t,wchar_t_to_python_str>();

<< static PyObject* convert(wchar_t* const& w)
>> static PyObject* convert(wchar_t const& w)

<<    wchar_t* w2 = w;
<<   while(*w2++ != 0){
<<      s += *w2;
>>   wchar_t w2 = w;
>>   while(w2++ != 0){
>>      s += w2;

and the function signature:

<< void testArgument(wchar_t * w){
>> void testArgument(const wchar_t &w){

this make everything works fine:

I don't know how get this working with wchar_t* in function signature.
Maybe create a class_ for w_char_t.



On Mon, Jun 22, 2009 at 2:27 PM, Nicolas Lara<nicolaslara at gmail.com> wrote:
> 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/
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>



-- 
BR
Renato Araujo Oliveira Filho


More information about the Cplusplus-sig mailing list