Re: [C++-sig] Differences between 32-bit and 64-bit python25.lib

2009-06-22 Thread Lars Viklund
On Mon, Jun 22, 2009 at 09:52:35AM +0300, Jesse Lehrman wrote:
> It seems that most of the exports in the 32-bit version have a preceding 
> underscore while in the 64-bit version they don't. For example:
> 
> python25.lib 32-bit:
>   _PyFloat_AsDouble
> 
> python25.lib 64-bit:
>   PyFloat_AsDouble
> 
> Does anybody have an idea of why this is done and how I can get around it?

x86 has a whole slew of calling conventions, and in order to
disambiguate between them, symbols are decorated according to the
convention used [1].

In this case, a leading underscore means it's cdecl.

With x86_64, there's a new and shiny calling convention [2], replacing
all the old ones. As there's only one, there's no need to decorate that
one with anything in a symbol, thus the lack of _ in your 64-bit symbol.

This is all from a Windows perspective of course, as that's your
context.

As for getting things to do the right thing, I'm unsure.

[1] http://blogs.msdn.com/oldnewthing/archive/2004/01/08/48616.aspx
[2] http://blogs.msdn.com/freik/archive/2005/03/17/398200.aspx

-- 
Lars Viklund | z...@acc.umu.se | 070-310 47 07
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


[C++-sig] embedding python in C++: exceptions, a newbie Q

2009-06-22 Thread Yuval Nahmany
Hi,
I am trying to use boost.python to wrap some classes in an
application, and have python embedded in my app and make some
instances from the application accessible thru simple script.
I got the impression that with boost python it should be quite simple
for basics, but I cannot have a simple code as bellow run:

1. If I uncomment the  //import("MyModule"); I get a runtime error -
and an application crash. And without it- I get an exception that the
C++ class CMyWrap is not associated with a python class.

2. If I just try to do a simpler thing like //exec("dir(__main__)",
main_namespace); I get "bad argument to an internal function" as an
exception.

I use python26_d.dll/ python26_d.lib and
libboost_python-vc90-mt-1_39.lib (boost 1.39 compiled as static lib).

Can you please help?
Can you refer me to any documentation that may help?
TIA,

Yuv.

class CMyWrap
{
public:
string Greet()
{
return "I'm the dude!?";
}
};

class CppClass {
public:
int getNum() {
return 7;
}
};

BOOST_PYTHON_MODULE(MyModule)
{
class_("CMyWrap")
.def("greet", &CMyWrap::Greet);
}


int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) {
int nRetCode = 0;
CMyWrap myObj;
try
{
PyImport_AppendInittab( "MyModule", &initMyModule);

Py_Initialize();
object main_module = import("__main__");

object main_namespace = main_module.attr("__dict__");
//import("MyModule");

//exec("dir(__main__)", main_namespace);
main_namespace["myObj"] = ptr(&myObj);

}
catch( error_already_set )
{
PyErr_Print();
}

Py_Finalize();

return nRetCode;
}



--
Yuval Nahmany
cell. 054-2020665
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


[C++-sig] wchar_t* type conversion

2009-06-22 Thread Nicolas Lara
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());
 }

 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*)
                    data)->storage.bytes;

   wchar_t* w = new wchar_t[l];
   for(int i=0;iconvertible = w;
 }
};
 void init_module()
 {
   to_python_converter();
   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@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] wchar_t* type conversion

2009-06-22 Thread Renato Araujo
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 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());
>  }
>
>  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*)
>                     data)->storage.bytes;
>
>    wchar_t* w = new wchar_t[l];
>    for(int i=0;i      w[i] = value[i];
>    }
>    data->convertible = w;
>  }
> };
>  void init_module()
>  {
>    to_python_converter();
>    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@python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig
>



-- 
Renato Araujo Oliveira Filho
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] wchar_t* type conversion

2009-06-22 Thread Nicolas Lara
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 
#include 

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());
  }

  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*)
 data)->storage.bytes;

wchar_t* w = new wchar_t[l];
for(int i=0;iconvertible = w;
  }
};

void init_module()
{
  to_python_converter();
  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("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/ in ()

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/ in ()

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/ in ()

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 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 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());
>>  }
>>
>>  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*)
>>                     data)->storage.bytes;
>>
>>    wchar_t* w = new wchar_t[l];
>>    for(int i=0;i>      w[i] = value[i];
>>    }
>

Re: [C++-sig] wchar_t* type conversion

2009-06-22 Thread Renato Araujo
Hi Nicolas

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

<< to_python_converter();
>> to_python_converter();

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

<>   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 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 
> #include 
>
> 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());
>  }
>
>  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*)
>                     data)->storage.bytes;
>
>    wchar_t* w = new wchar_t[l];
>    for(int i=0;i      w[i] = value[i];
>    }
>    data->convertible = w;
>  }
> };
>
> void init_module()
> {
>  to_python_converter();
>  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      p[i]=s[i];
>    return p;
>  }
>
>  void testArgument(wchar_t * w){
>    printf("ok\n");
>  }
> };
>
>
> BOOST_PYTHON_MODULE(test){
>  init_module();
>  class_("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/ in ()
>
> 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/ in ()
>
> 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/ in ()
>
> 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 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 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;
>>>   

Re: [C++-sig] wchar_t* type conversion

2009-06-22 Thread Nicolas Lara
Thanks!
I'm trying to create an interface for a third party library, so I
can't actually change it. I also tried using ctypes.pointer but didn't
work either. I'll probably need to create a wrapper that does the type
conversion.

Thanks again Renato!
If anyone knows how to make it work with wchar_t* i'd appreciate it!

On Mon, Jun 22, 2009 at 11:57 AM, Renato Araujo wrote:
> Hi Nicolas
>
> At my first look I get this working changing the register function:
>
> << to_python_converter();
>>> to_python_converter();
>
> << 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 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 
>> #include 
>>
>> 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());
>>  }
>>
>>  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*)
>>                     data)->storage.bytes;
>>
>>    wchar_t* w = new wchar_t[l];
>>    for(int i=0;i>      w[i] = value[i];
>>    }
>>    data->convertible = w;
>>  }
>> };
>>
>> void init_module()
>> {
>>  to_python_converter();
>>  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>      p[i]=s[i];
>>    return p;
>>  }
>>
>>  void testArgument(wchar_t * w){
>>    printf("ok\n");
>>  }
>> };
>>
>>
>> BOOST_PYTHON_MODULE(test){
>>  init_module();
>>  class_("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/ in ()
>>
>> 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/ in ()
>>
>> 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/ in ()
>>
>> 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 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 wrote:
 Hello,
 I'm new to Boost::Python and am encountering 

[C++-sig] pybindgen: Why does pybindgen want to call constructors for a singleton class?

2009-06-22 Thread J. Michael Owen
I'm looking at wrapping a C++ singleton with pybindgen, and it seems  
that if I expose the method for getting the instance to python the  
generated code wants to call a copy constructor, which seems wrong to  
me.  If for instance I define a class "A" as a singleton:


class A {
public:
  static A* instancePtr() {
if (A::mInstancePtr == 0) A::mInstancePtr = new A;
return mInstancePtr;
  }
private:
  A();
  A(const A& rhs);
  A& operator=(const A& rhs);
  static A* mInstancePtr;
};

and I wrap A and its instance method like so:

mod = Module("singleton_example")
mod.add_include('"singleton_example.hh"')
x = mod.add_class("A", is_singleton=True)
x.add_method("instancePtr", retval("A*", caller_owns_return=False), [])

pybindgen generates the following code for the instancePtr method:

PyObject *
_wrap_PyA_instancePtr(PyA *self)
{
PyObject *py_retval;
A *retval;
PyA *py_A;

retval = self->obj->instancePtr();
if (!(retval)) {
Py_INCREF(Py_None);
return Py_None;
}
py_A = PyObject_New(PyA, &PyA_Type);
py_A->obj = new A(*retval);
py_retval = Py_BuildValue((char *) "N", py_A);
return py_retval;
}

As you can see it is trying to construct a new object with a copy of  
the A retval parameter (the line that reads "py_A->obj = new  
A(*retval);".  This is of course forbidden because all of A's  
constructors are private -- as a singleton we don't want anyone  
calling constructors on this object.  Moreover, since I exposed  
"instancePtr" as returning a pointer I did not expect any copies to be  
generated anyway -- I'd like to see the pointer "retval" sent back  
directly (even if this wasn't a singleton).  Am I missing some syntax  
here to prevent pybindgen from trying to make these copies?


Thanks!

Mike.

___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig


Re: [C++-sig] pybindgen: Why does pybindgen want to call constructors for a singleton class?

2009-06-22 Thread Gustavo Carneiro
2009/6/22 J. Michael Owen 

> I'm looking at wrapping a C++ singleton with pybindgen, and it seems that
> if I expose the method for getting the instance to python the generated code
> wants to call a copy constructor, which seems wrong to me.  If for instance
> I define a class "A" as a singleton:
>
> class A {
> public:
>  static A* instancePtr() {
>if (A::mInstancePtr == 0) A::mInstancePtr = new A;
>return mInstancePtr;
>  }
> private:
>  A();
>  A(const A& rhs);
>  A& operator=(const A& rhs);
>  static A* mInstancePtr;
> };
>
> and I wrap A and its instance method like so:
>
> mod = Module("singleton_example")
> mod.add_include('"singleton_example.hh"')
> x = mod.add_class("A", is_singleton=True)
> x.add_method("instancePtr", retval("A*", caller_owns_return=False), [])
>
> pybindgen generates the following code for the instancePtr method:
>
> PyObject *
> _wrap_PyA_instancePtr(PyA *self)
> {
>PyObject *py_retval;
>A *retval;
>PyA *py_A;
>
>retval = self->obj->instancePtr();
>if (!(retval)) {
>Py_INCREF(Py_None);
>return Py_None;
>}
>py_A = PyObject_New(PyA, &PyA_Type);
>py_A->obj = new A(*retval);
>py_retval = Py_BuildValue((char *) "N", py_A);
>return py_retval;
> }
>
> As you can see it is trying to construct a new object with a copy of the A
> retval parameter (the line that reads "py_A->obj = new A(*retval);".  This
> is of course forbidden because all of A's constructors are private -- as a
> singleton we don't want anyone calling constructors on this object.
>  Moreover, since I exposed "instancePtr" as returning a pointer I did not
> expect any copies to be generated anyway -- I'd like to see the pointer
> "retval" sent back directly (even if this wasn't a singleton).  Am I missing
> some syntax here to prevent pybindgen from trying to make these copies?


It tries to copy because you say caller_owns_return=False, pybindgen needs
to copy the object so that the wrapper can own the object.  What you can do
here is use caller_owns_return=True instead of False.  It's OK in this case;
because of the is_singleton option, the C++ wrapped object will never be
freed when the wrapper is destroyed.

-- 
Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig

Re: [C++-sig] pybindgen: Why does pybindgen want to call constructors for a singleton class?

2009-06-22 Thread J. Michael Owen
Ah, I see!  That does the trick!  Thank you very much.  I was clearly  
confused about what "caller_owns_return" meant  -- I had it backwards.


Mike.

On Jun 22, 2009, at 5:11 PM, Gustavo Carneiro wrote:




2009/6/22 J. Michael Owen 
I'm looking at wrapping a C++ singleton with pybindgen, and it seems  
that if I expose the method for getting the instance to python the  
generated code wants to call a copy constructor, which seems wrong  
to me.  If for instance I define a class "A" as a singleton:


class A {
public:
 static A* instancePtr() {
   if (A::mInstancePtr == 0) A::mInstancePtr = new A;
   return mInstancePtr;
 }
private:
 A();
 A(const A& rhs);
 A& operator=(const A& rhs);
 static A* mInstancePtr;
};

and I wrap A and its instance method like so:

mod = Module("singleton_example")
mod.add_include('"singleton_example.hh"')
x = mod.add_class("A", is_singleton=True)
x.add_method("instancePtr", retval("A*", caller_owns_return=False),  
[])


pybindgen generates the following code for the instancePtr method:

PyObject *
_wrap_PyA_instancePtr(PyA *self)
{
   PyObject *py_retval;
   A *retval;
   PyA *py_A;

   retval = self->obj->instancePtr();
   if (!(retval)) {
   Py_INCREF(Py_None);
   return Py_None;
   }
   py_A = PyObject_New(PyA, &PyA_Type);
   py_A->obj = new A(*retval);
   py_retval = Py_BuildValue((char *) "N", py_A);
   return py_retval;
}

As you can see it is trying to construct a new object with a copy of  
the A retval parameter (the line that reads "py_A->obj = new  
A(*retval);".  This is of course forbidden because all of A's  
constructors are private -- as a singleton we don't want anyone  
calling constructors on this object.  Moreover, since I exposed  
"instancePtr" as returning a pointer I did not expect any copies to  
be generated anyway -- I'd like to see the pointer "retval" sent  
back directly (even if this wasn't a singleton).  Am I missing some  
syntax here to prevent pybindgen from trying to make these copies?


It tries to copy because you say caller_owns_return=False, pybindgen  
needs to copy the object so that the wrapper can own the object.   
What you can do here is use caller_owns_return=True instead of  
False.  It's OK in this case; because of the is_singleton option,  
the C++ wrapped object will never be freed when the wrapper is  
destroyed.


--
Gustavo J. A. M. Carneiro
INESC Porto, Telecommunications and Multimedia Unit
"The universe is always one step beyond logic." -- Frank Herbert
___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http:// mail.python.org/mailman/listinfo/cplusplus-sig


___
Cplusplus-sig mailing list
Cplusplus-sig@python.org
http://mail.python.org/mailman/listinfo/cplusplus-sig