Opened 11 years ago

Closed 8 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
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);

#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, 
	//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, 

	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

Attachments (0)

Change History (3)

comment:1 Changed 10 years ago by Dave Abrahams

Description: modified (diff)

Fix formatting mess

comment:2 Changed 10 years ago by Dave Abrahams

Milestone: To Be DeterminedBoost 1.36.0
Status: newassigned

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

comment:3 Changed 8 years ago by Dave Abrahams

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.

Modify Ticket

Change Properties
Set your email in Preferences
as closed The owner will remain Dave Abrahams.
The resolution will be deleted.

Add Comment

E-mail address and name can be saved in the Preferences.

Note: See TracTickets for help on using tickets.