Opened 15 years ago

Closed 13 years ago

#1179 closed Bugs (invalid)

[boost.python] can not export a union in VC2005sp1

Reported by: qiaozhiqiang@… Owned by: Dave Abrahams
Milestone: Boost 1.36.0 Component: python USE GITHUB
Version: Boost 1.34.0 Severity: Problem
Keywords: python export union Cc:

Description (last modified by Dave Abrahams)

// Visual V++ 2005(8.0) sp1, union not is_class.
// because there is BOOST_STATIC_ASSERT(is_class<T>::value) in make_instance_impl
// can not export union. eg, class_<union my_u>
// can not return_internal_reference<> when not is_class, eg, return char*, char&, union u&
// delete BOOST_STATIC_ASSERT(is_class<T>::value); of make_instance_impl, then compile OK, and work not all OK
boost/python/object/make_instance.hpp
template <class T, class Holder, class Derived>
struct make_instance_impl
{
    typedef objects::instance<Holder> instance_t;
        
    template <class Arg>
    static inline PyObject* execute(Arg& x)
    {   
    		// must is_class ?? BOOST_STATIC_ASSERT(is_class<T>::value || is_union<T>::value);
        BOOST_STATIC_ASSERT(is_class<T>::value);

///////////////////////////////
#include <boost/python.hpp>
using namespace boost::python;
 
union my_u
{
	int a;
	char b;
	char& get_ref()
	{
		return b;
	}
	char* get_ptr()
	{
		return *b;
	}
}

struct my_s
{
	my_u u;
	my_u& get_ref()
	{
		return u;
	}
	my_u* get_ptr()
	{
		return &u;
	}
};

void my_module()
{

	//1. compile ERROR: my_u not is_class, my_u is_union, I modify one line in make_instance.hpp
	// BOOST_STATIC_ASSERT(is_class<T>::value)	to  BOOST_STATIC_ASSERT(is_class<T>::value || is_union<T>::value)
	// and work OK, why not export an union?
	class_<my_u > u_class("my_u", init< >());	
	u_class.def_readwrite("a", &my_u::a);
	u_class.def_readwrite("b", &my_u::b);
	
	
	//2. compile ERROR:  char not is_class, delete BOOST_STATIC_ASSERT(is_class<T>::value), but run error
	u_class.def("get_ref", &my_u::get_ref, return_internal_reference< >());
	
	//3. compile ERROR:  char not is_class, delete BOOST_STATIC_ASSERT(is_class<T>::value), but run error
	u_class.def("get_ptr", &my_u::get_ptr, return_internal_reference< >());
	
	//4. compile OK, but run ERROR, I need it return a char
	.def("get_value", &my_u::get_ptr, 
	         return_value_policy<return_by_value>());
	         
	//5. compile ERROR, char* is not a reference, I need but have no copy_non_const_pointer
	u_class.def("get_copy", &my_u::get_ptr, 
	         return_value_policy<copy_non_const_reference>());


	class_<my_s >  s_class("my_s", init<  >());
	
	//6. compile OK, buy run ERROR: 
	// s = my_s()
	// s.u.a = 100
	// print s.u.a
	// but output s.u.a != 100  !!!
	// s.u.a = 100  is  s.get_u().set_a(100) and get_u() not return u(is_union) by ref ?
	s_class.def_readwrite("u", &my_s::u);
	
	// 7. compile ERROR: my_u not is_class, is_union, modify BOOST_STATIC_ASSERT(is_class<T>::value)	to
	// BOOST_STATIC_ASSERT(is_class<T>::value || is_union<T>::value)
	s_class.def("get_ptr", &my_s::get_ptr, return_internal_reference<>());  
	s_class.def("get_ref", &my_s::get_ref, return_value_policy<return_by_value>());//compile ok
}

Change History (3)

comment:1 by Dave Abrahams, 14 years ago

Description: modified (diff)

Fix formatting mess

comment:2 by Dave Abrahams, 14 years ago

Milestone: To Be DeterminedBoost 1.36.0
Status: newassigned

OK, looks like there's an easy and reasonable low-risk fix.

comment:3 by Dave Abrahams, 13 years ago

Resolution: invalid
Status: assignedclosed

I'm sorry; I don't know what sort of fix I had in mind, but this code couldn't compile as given, even if Boost.Python were changed as requested.

  1. There are several syntax errors.
  1. You can only return_internal_reference<> to a wrapped class type, not a char; don't forget, char gets translated into a Python string and Python strings are immutable.
  1. You're using copy_non_const_reference on a pointer to char, but it intentionally only works on a pointer to reference.

If you can give me an example that doesn't try to do things that are intentionally illegal (other than wrapping a union for Python) then I might be able to try to make this work. Otherwise, closing as invalid.

Note: See TracTickets for help on using tickets.