/src/runtime/methodwrapper.cs

https://github.com/Unity-Technologies/pythonnet · C# · 56 lines · 37 code · 10 blank · 9 comment · 5 complexity · fc0b59a0c7846193a30e87b34baf916c MD5 · raw file

  1. using System;
  2. namespace Python.Runtime
  3. {
  4. /// <summary>
  5. /// A MethodWrapper wraps a static method of a managed type,
  6. /// making it callable by Python as a PyCFunction object. This is
  7. /// currently used mainly to implement special cases like the CLR
  8. /// import hook.
  9. /// </summary>
  10. internal class MethodWrapper
  11. {
  12. public IntPtr mdef;
  13. public IntPtr ptr;
  14. private ThunkInfo _thunk;
  15. private bool _disposed = false;
  16. public MethodWrapper(Type type, string name, string funcType = null)
  17. {
  18. // Turn the managed method into a function pointer
  19. _thunk = Interop.GetThunk(type.GetMethod(name), funcType);
  20. // Allocate and initialize a PyMethodDef structure to represent
  21. // the managed method, then create a PyCFunction.
  22. mdef = Runtime.PyMem_Malloc(4 * IntPtr.Size);
  23. TypeManager.WriteMethodDef(mdef, name, _thunk.Address, 0x0003);
  24. ptr = Runtime.PyCFunction_NewEx(mdef, IntPtr.Zero, IntPtr.Zero);
  25. }
  26. public IntPtr Call(IntPtr args, IntPtr kw)
  27. {
  28. return Runtime.PyCFunction_Call(ptr, args, kw);
  29. }
  30. public void Release()
  31. {
  32. if (_disposed)
  33. {
  34. return;
  35. }
  36. _disposed = true;
  37. bool freeDef = Runtime.Refcount(ptr) == 1;
  38. Runtime.XDecref(ptr);
  39. if (freeDef && mdef != IntPtr.Zero)
  40. {
  41. Runtime.PyMem_Free(mdef);
  42. mdef = IntPtr.Zero;
  43. }
  44. }
  45. }
  46. }