@@ -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