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
关键修正点
- QueryInterface方法签名:必须接收两个参数,第二个参数对应C#的
out object,通过out_obj.Value赋值返回对象。 - 实现AddRef/Release:由于IErrorCallback继承自IRefCountable,这两个方法是强制实现的,需维护引用计数逻辑。
- QueryInterface逻辑:判断请求的接口GUID是否为当前类实现的接口,若是则返回自身并增加引用计数,否则返回
NoInterface状态。
内容的提问来源于stack exchange,提问作者shashanka.sunkara
相关产品推荐
相关产品推荐

