You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现C# IErrorCallback接口时QueryInterface方法未实现报错求助

解决Python实现C# IErrorCallback接口时的QueryInterface未实现错误

在Python中实现指定的C# IErrorCallback接口,调用相关方法后触发TypeError,提示Filament.Standard.DoErrorCallbacks类型的QueryInterface方法无实现。以下是相关代码、错误信息及解决方案:


C# IErrorCallback接口定义

// Assembly location: D:\Others\PROJECTS\Strahlerdauretest\NewFirmware\FilamentEnduranceTest\dlls\Fischer.Devices.Dpp.Sdk.dll
using Filament.Standard.hightemperature;
using Filament.Standard.highvoltage;
using Fiona;
using System.Runtime.InteropServices;

#nullable disable
namespace Filament.Standard
{
  [Guid("ee59bf8b-06a4-4633-8ec6-06ad9fb1a4e2")]
  public interface IErrorCallback : IObject, IRefCountable
  {
    Status OnHvDeviation([In] HvDeviationData recordData);

    Status OnAnodeCurrentDeviation([In] DeviationTime[] recordData);

    Status OnHtDeviation([In] DeviationSeverity level);
  }
}

原Python实现代码

class DoErrorCallbacks(IErrorCallback):
    __namespace__ = "Filament.Standard"

    def OnHvDeviation(self, recordData):
        recordTime = recordData.timestamp
        print(f"Voltage drop begin {recordTime.day}.{recordTime.month}.{recordTime.year} {recordTime.hour}:{recordTime.minute}:{recordTime.second}.{recordTime.subseconds}")

        for seg in recordData.deviationSegments:
            if seg.category == recordData.deviationSegments.Invalid:
                break
            print(f"Category: {seg.category} Count: {seg.samplesInCategory}")

        return status.Ok

    def OnHtDeviation(self, level):
        if level == DeviationSeverity.Warning:
            print("\n-----------------------")
            print("Warning! Tube temperature reached high level.")
            print("-----------------------")
        elif level == DeviationSeverity.Critical:
            print("\n-----------------------")
            print("Error! Tube temperature reached critical level. -> Tube got disabled")
            print("-----------------------")
        return status.Ok

    def OnAnodeCurrentDeviation(self, recordData):
        recordBegin = recordData[0]
        recordEnd = recordData[1]

        print(f"\nOver current begin {recordBegin.day}.{recordBegin.month}.{recordBegin.year} {recordBegin.hour}:{recordBegin.minute}:{recordBegin.second}.{recordBegin.subseconds}")
        print(f"Over current end   {recordEnd.day}.{recordEnd.month}.{recordEnd.year} {recordEnd.hour}:{recordEnd.minute}:{recordEnd.second}.{recordEnd.subseconds}")

        return status.Ok

    def QueryInterface(self, id):
        return status.NotImplemented

调用代码

error_callback  = DoErrorCallbacks()
self._ifilament_device.SetErrorCallback(error_callback)

错误信息

class DoErrorCallbacks(IErrorCallback):
TypeError: Die Methode "QueryInterface" im Typ "Filament.Standard.DoErrorCallbacks" der Assembly "Python.Runtime.Dynamic, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" hat keine Implementierung.

参考接口定义

Fiona.IObject

// Assembly location: D:\Others\PROJECTS\Strahlerdauretest\NewFirmware\FilamentEnduranceTest\dlls\FiONA.dll
using System;
using System.Runtime.InteropServices;

#nullable disable
namespace Fiona
{
  [Guid("53f23da3-51f2-4804-a315-30150216905a")]
  public interface IObject : IRefCountable
  {
    Status QueryInterface(Guid interfaceId, out object o);
  }
}

Fiona.IRefCountable

// Assembly location: D:\Others\PROJECTS\Strahlerdauretest\NewFirmware\FilamentEnduranceTest\dlls\FiONA.dll
#nullable disable
namespace Fiona
{
  public interface IRefCountable
  {
    long AddRef();

    long Release();
  }
}

解决方案

问题核心是Python实现的方法签名与C#接口不匹配,且缺少IRefCountable接口的强制实现方法。以下是修正后的代码:

class DoErrorCallbacks(IErrorCallback):
    __namespace__ = "Filament.Standard"
    _ref_count = 0

    def OnHvDeviation(self, recordData):
        recordTime = recordData.timestamp
        print(f"Voltage drop begin {recordTime.day}.{recordTime.month}.{recordTime.year} {recordTime.hour}:{recordTime.minute}:{recordTime.second}.{recordTime.subseconds}")

        for seg in recordData.deviationSegments:
            if seg.category == recordData.deviationSegments.Invalid:
                break
            print(f"Category: {seg.category} Count: {seg.samplesInCategory}")

        return status.Ok

    def OnHtDeviation(self, level):
        if level == DeviationSeverity.Warning:
            print("\n-----------------------")
            print("Warning! Tube temperature reached high level.")
            print("-----------------------")
        elif level == DeviationSeverity.Critical:
            print("\n-----------------------")
            print("Error! Tube temperature reached critical level. -> Tube got disabled")
            print("-----------------------")
        return status.Ok

    def OnAnodeCurrentDeviation(self, recordData):
        recordBegin = recordData[0]
        recordEnd = recordData[1]

        print(f"\nOver current begin {recordBegin.day}.{recordBegin.month}.{recordBegin.year} {recordBegin.hour}:{recordBegin.minute}:{recordBegin.second}.{recordBegin.subseconds}")
        print(f"Over current end   {recordEnd.day}.{recordEnd.month}.{recordEnd.year} {recordEnd.hour}:{recordEnd.minute}:{recordEnd.second}.{recordEnd.subseconds}")

        return status.Ok

    # 修正QueryInterface签名,匹配C#接口的out参数要求
    def QueryInterface(self, interfaceId, out_obj):
        # 校验请求的接口是否为当前类实现的接口
        target_guids = [IErrorCallback.__guid__, IObject.__guid__, IRefCountable.__guid__]
        if interfaceId in target_guids:
            self.AddRef()
            out_obj.Value = self
            return status.Ok
        out_obj.Value = None
        return status.NoInterface

    # 实现IRefCountable的AddRef方法
    def AddRef(self):
        self._ref_count += 1
        return self._ref_count

    # 实现IRefCountable的Release方法
    def Release(self):
        self._ref_count -= 1
        if self._ref_count == 0:
            # 引用计数归0时可执行资源清理逻辑
            del self
        return self._ref_count

关键修正点

  1. QueryInterface方法签名:必须接收两个参数,第二个参数对应C#的out object,通过out_obj.Value赋值返回对象。
  2. 实现AddRef/Release:由于IErrorCallback继承自IRefCountable,这两个方法是强制实现的,需维护引用计数逻辑。
  3. QueryInterface逻辑:判断请求的接口GUID是否为当前类实现的接口,若是则返回自身并增加引用计数,否则返回NoInterface状态。

内容的提问来源于stack exchange,提问作者shashanka.sunkara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:43:31