@@ -619,6 +619,8 @@ def virtual_function(
619619 if return_type not in DataType.values:
620620 return_type = self.create_converter(return_type)
621621
622+ funcs = {}
623+
622624 class fget(object):
623625 def __set_name__(fget_self, owner, name):
624626 fget_self.name = name
@@ -628,22 +630,26 @@ def __get__(fget_self, obj, cls=None):
628630 if obj is None:
629631 return fget_self
630632
631- # Create the virtual function
632- func = obj.make_virtual_function(
633- index,
634- convention,
635- args,
636- return_type
637- )
633+ # Get the vtable address
634+ address = obj._ptr().get_pointer().address
635+ # Search function cache by vtable address
636+ func = funcs.get(address, None)
637+
638+ if func is None:
639+ # Create the virtual function cache it
640+ func = obj.make_virtual_function(
641+ index,
642+ convention,
643+ args,
644+ return_type
645+ )
646+ funcs[address] = func
638647
639648 # Wrap it using MemberFunction, so we don't have to pass the this
640649 # pointer anymore
641650 func = MemberFunction(self, return_type, func, obj)
642651 func.__doc__ = doc
643652
644- # Set the MemberFunction as an attribute to the instance.
645- setattr(obj, fget_self.name, func)
646-
647653 return func
648654
649655 return fget()
@@ -696,9 +702,6 @@ def __get__(fget_self, obj, cls=None):
696702 m_func = MemberFunction(self, return_type, func, obj)
697703 m_func.__doc__ = doc
698704
699- # Set the MemberFunction as an attribute to the instance.
700- setattr(obj, fget_self.name, m_func)
701-
702705 return m_func
703706
704707 return func
0 commit comments