diff --git a/pybindgen/cppattribute.py b/pybindgen/cppattribute.py index f830bd0..2e3b18c 100644 --- a/pybindgen/cppattribute.py +++ b/pybindgen/cppattribute.py @@ -136,7 +136,10 @@ class CppInstanceAttributeSetter(PySetter): if self.setter is not None: ## if we have a setter method, redirect the value to a temporary variable - value_var = self.declarations.declare_variable(self.return_value.ctype, 'tmp_value') + if not self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR: + value_var = self.declarations.declare_variable(self.return_value.ctype, 'tmp_value') + else: + value_var = self.declarations.reserve_variable('tmp_value') self.return_value.value = value_var else: ## else the value is written directly to a C++ instance attribute diff --git a/pybindgen/cppclass.py b/pybindgen/cppclass.py index c9eeb9d..63653f5 100644 --- a/pybindgen/cppclass.py +++ b/pybindgen/cppclass.py @@ -335,7 +335,6 @@ class CppClass(object): """Register this C++ class as value return""" CTYPES = [name] cpp_class = self - REQUIRES_ASSIGNMENT_CONSTRUCTOR = True self.ThisClassReturn = ThisClassReturn self.ThisClassRefReturn = ThisClassReturn @@ -1115,6 +1114,7 @@ class CppClassReturnValue(CppClassReturnValueBase): "Class return handlers" CTYPES = [] cpp_class = CppClass('dummy') # CppClass instance + REQUIRES_ASSIGNMENT_CONSTRUCTOR = True def __init__(self, ctype): """override to fix the ctype parameter with namespace information""" @@ -1151,7 +1151,8 @@ class CppClassReturnValue(CppClassReturnValueBase): self.cpp_class.pystruct+'*', "tmp_%s" % self.cpp_class.name) wrapper.parse_params.add_parameter( 'O!', ['&'+self.cpp_class.pytypestruct, '&'+name]) - wrapper.after_call.write_code('%s = *%s->obj;' % (self.value, name)) + wrapper.after_call.write_code('%s %s = *%s->obj;' % + (self.cpp_class.full_name, self.value, name)) diff --git a/pybindgen/cppmethod.py b/pybindgen/cppmethod.py index 5aa44a6..ca48807 100644 --- a/pybindgen/cppmethod.py +++ b/pybindgen/cppmethod.py @@ -378,7 +378,7 @@ class CppVirtualMethodParentCaller(CppMethod): def generate_declaration(self, code_sink, extra_wrapper_parameters=()): ## We need to fake generate the code (and throw away the ## result) only in order to obtain correct method signature. - tmp_sink = codesink.MemoryCodeSink() + tmp_sink = codesink.NullCodeSink() self.generate_body(tmp_sink, gen_call_params=[self.class_]) if self.overload_index is None: diff --git a/pybindgen/typehandlers/base.py b/pybindgen/typehandlers/base.py index 1033146..923db64 100644 --- a/pybindgen/typehandlers/base.py +++ b/pybindgen/typehandlers/base.py @@ -422,6 +422,23 @@ class DeclarationsScope(object): self._declarations.writeln(decl + ';') return varname + def reserve_variable(self, name): + """Reserve a variable name, to be used later. + name -- base name of the variable; actual name used can be + slightly different in case of name conflict. + """ + try: + num = self.declared_variables[name] + except KeyError: + num = 0 + num += 1 + self.declared_variables[name] = num + if num == 1: + varname = name + else: + varname = "%s%i" % (name, num) + return varname + def get_code_sink(self): """Returns the internal MemoryCodeSink that holds all declararions.""" return self._declarations @@ -511,7 +528,8 @@ class ReverseWrapperBase(object): assert all([isinstance(mod, str) for mod in decl_modifiers]) self.declarations.declare_variable('PyObject*', 'py_retval') - if self.return_value.ctype != 'void': + if self.return_value.ctype != 'void' \ + and not self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR: self.declarations.declare_variable(self.return_value.ctype, 'retval') ## convert the input parameters @@ -673,7 +691,8 @@ class ForwardWrapperBase(object): if self.return_value is not None: self.declarations.declare_variable('PyObject*', 'py_retval') if (not self.no_c_retval and self.return_value is not None - and self.return_value.ctype != 'void'): + and self.return_value.ctype != 'void' + and not self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR): self.declarations.declare_variable(self.return_value.ctype, 'retval')