C# 类成员函数指针和 c++ this->*func

C# class member function pointer and c++ this->*func

提问人:jokn 提问时间:1/13/2022 最后编辑:πάντα ῥεῖjokn 更新时间:1/13/2022 访问量:221

问:

我正在将一个C++项目移植到 C#,并且对 this->function 指针有疑问。 在 C++ 中,它运行良好:

class ModbusData {
bool ScannAll(void (ModbusData::*func)(MBSFrame *Frame), MBSFrame *Frame)
{
    if (Frame->MatchAddress(MyBaseAddr, MySize)) {
        (this->*func) (Frame);
        return true;
    } else {
        if (NextData != 0) {
            return NextData->ScannAll(func, Frame);
        }
        return false;
    }
}

};

该函数的用法如下

gCoils->ScannAll(&ModbusData::ReadMultiple, Frame);

这是我的 C# atrempt:

class ModbusData {
    public delegate void ModDataFunc(MBSFrame Frame);
    public bool ScannAll(ModDataFunc func, MBSFrame Frame)
    {
        if (Frame.MatchAddress(MyBaseAddr, MySize)) {
            func.Invoke(Frame);
            RaiseValueReadEvent(Frame.DataAddress, Frame.DataCount);
            return true;
        } else {
            if (NextData != null) {
            return NextData.ScannAll(func, Frame);
            }
            return false;
        }
    }
};

//  usage
gCoils.ScannAll(gCoils.ReadMultiple, Frame);

问题出在类的下一个 instace 的递归调用 NextData.ScannAll(函数,框架); 因为类成员变量不再有效。

我在 C# 中了解到委托函数在某种程度上是静态的。解决方案可能是同时传递类引用。 但也许 sombody 有更好的主意。

C# 指针 委托此

评论

0赞 PaulMcKenzie 1/13/2022
关于移植的注释 -- 您的移植尝试是尝试从语言 A 到语言 B 的逐行和/或逐模块翻译失败的原因。C++有它的做事方式,C#有它的方式,这些方式可以大不相同,以实现相同的目标。此外,试图使语言 B 看起来像语言 A,几乎总是会导致语言 B 具有低效的代码、有缺陷的代码或对了解语言 B 的人来说看起来很奇怪的代码。
1赞 PMF 1/13/2022
在 C# 中,委托可以指向静态函数或成员函数。如果是后者,则对象引用包含在委托中。所以这可能不是问题。你得到什么错误?
0赞 Scott Hannen 1/13/2022
问题出在哪里并不明显。有错误吗?某些东西是否未按预期工作?甚至递归也不明显。名为的类具有一个调用的方法,该方法调用不同类中具有相同名称的方法。ModbusDataScannAll
0赞 jokn 1/13/2022
在 C# 中,当调用 ScannAll() 时,我使用指向类的特定实例 (gCoils.ReadMultiple) 的指针(委托),其中在 C++ 中,指针作为类定义 (&ModbusData::ReadMultiple) 的相对地址库。后来在 ScannAll() 中,(this->*func)() 创造了魔力。请注意,ScannAll() 使用 ModbusData 类的另一个实例进行回避调用。我忘了解释一下,在C#中,当调用NextData.ScannAll()时,有一些类成员vaiables(MyBaseAddr,MySize)不再有效

答:

1赞 Sohaib Jundi 1/13/2022 #1

您可以创建另一个接受且未绑定到指定目标的委托,并将当前实例传递给该委托。ModbusDataMBSFrame

public delegate void ModDataFunc(MBSFrame Frame);
private delegate void StaticModDataFunc(ModbusData ths, MBSFrame Frame);

private bool ScannAll(StaticModDataFunc func, MBSFrame Frame)
{
  if (Frame.MatchAddress(MyBaseAddr, MySize))
  {
    func(this, Frame);
    RaiseValueReadEvent(Frame.DataAddress, Frame.DataCount);
    return true;
  }
  else
  {
    if (NextData != null)
    {
      return NextData.ScannAll(func, Frame);
    }
    return false;
  }
}

public bool ScannAll(ModDataFunc func, MBSFrame Frame)
{
  return ScannAll(func.Method.CreateDelegate<StaticModDataFunc>(), Frame);
}

评论

0赞 jokn 1/13/2022
事实上,这就是我之前提到的,使用成员函数传递 this 指针。但是此时我的成员函数是静态的,因为相关类在参数列表中。为了让我的问题更清楚,我将创建一个新问题。
0赞 Sohaib Jundi 1/13/2022
它不会变成静态的,第一个参数会变成 this 指针。