9

Python for .NET を使用して呼び出しようとしている C# で記述されたライブラリが提供されました。

インスタンスが必要なプライマリ クラスには、次のようなコンストラクタがあります。

GDhuClient(IGDhuSettings)

IGDhuSettingsインターフェイスを実装する (公開された) クラスはありません。Python クラスを作成して実装する場合、たとえば、

class PyGDhuSettings(IGDhuSettings):
    ...

TypeError: interface takes exactly one argumentメソッドがない場合、__new__または通常の方法で定義した場合は、次のようになります。

def __new__(cls):
    return super().__new__(cls)

クラスであるかのようにインターフェイスをインスタンス化しようとすると、同じエラーが発生するか (引数がないか、1 つ以上) <whatever> does not implement IGDhuSettings、単一の引数を渡した場合に発生します。

Python for .NETのソースを見ると、

using System;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Python.Runtime
{
    /// <summary>
    /// Provides the implementation for reflected interface types. Managed
    /// interfaces are represented in Python by actual Python type objects.
    /// Each of those type objects is associated with an instance of this
    /// class, which provides the implementation for the Python type.
    /// </summary>
    internal class InterfaceObject : ClassBase
    {
        internal ConstructorInfo ctor;

        internal InterfaceObject(Type tp) : base(tp)
        {
            var coclass = (CoClassAttribute)Attribute.GetCustomAttribute(tp, cc_attr);
            if (coclass != null)
            {
                ctor = coclass.CoClass.GetConstructor(Type.EmptyTypes);
            }
        }

        private static Type cc_attr;

        static InterfaceObject()
        {
            cc_attr = typeof(CoClassAttribute);
        }

        /// <summary>
        /// Implements __new__ for reflected interface types.
        /// </summary>
        public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
        {
            var self = (InterfaceObject)GetManagedObject(tp);
            int nargs = Runtime.PyTuple_Size(args);
            Type type = self.type;
            object obj;

            if (nargs == 1)
            {
                IntPtr inst = Runtime.PyTuple_GetItem(args, 0);
                var co = GetManagedObject(inst) as CLRObject;

                if (co == null || !type.IsInstanceOfType(co.inst))
                {
                    Exceptions.SetError(Exceptions.TypeError, $"object does not implement {type.Name}");
                    return IntPtr.Zero;
                }

                obj = co.inst;
            }

            else if (nargs == 0 && self.ctor != null)
            {
                obj = self.ctor.Invoke(null);

                if (obj == null || !type.IsInstanceOfType(obj))
                {
                    Exceptions.SetError(Exceptions.TypeError, "CoClass default constructor failed");
                    return IntPtr.Zero;
                }
            }

            else
            {
                Exceptions.SetError(Exceptions.TypeError, "interface takes exactly one argument");
                return IntPtr.Zero;
            }

            return CLRObject.GetInstHandle(obj, self.pyHandle);
        }
    }
}

CoClass (定義されていない) がないか、それを実装するクラスを既に持っていない場合、Python で C# インターフェイスを実装する手段がわかりません。

ここで見逃しているニュアンスはありますか、それとも Python for .NET の制限ですか?

GitHub での議論: https://github.com/pythonnet/pythonnet/issues/674

4

1 に答える 1