gpt4 book ai didi

c# - 如何使用 SWIG 生成的接口(interface)在 C# 中正确向下转换?

转载 作者:搜寻专家 更新时间:2023-10-31 00:23:08 26 4
gpt4 key购买 nike

我有一个非常庞大且成熟的 C++ 代码库,我正在尝试使用 SWIG 为其生成 C# 接口(interface)。我无法更改实际的 C++ 代码本身,但我们可以使用 SWIG 提供的任何扩展/更新它的方式。我面临一个问题,即如下所示编写的 C++ 函数导致 C# 出现问题。

A* SomeClass::next(A*)

调用者可能会做类似的事情:

A* acurr = 0;
while( (acurr = sc->next(acurr)) != 0 ){
if( acurr isoftype B ){
B* b = (B*)a;
...do some stuff with b..
}
elseif( acurr isoftype C )
...
}

本质上,遍历一个元素容器,根据它们的真实类型,做一些不同的事情。遗憾的是,SWIG 为“下一个”函数生成的 C# 层执行以下操作:

return new A();

因此 C# 中的调用代码无法确定返回的对象是否实际上是派生类,它实际上看起来总是基类(这确实有意义)。我遇到了几种解决方案:

  1. 使用 %extend SWIG 关键字在对象上添加方法并最终调用 dynamic_cast。在我看来,这种方法的缺点是这需要您了解继承层次结构。就我而言,它相当大,我认为这是一个维护问题。
  2. 使用 %factory 关键字提供方法和派生类型,并让 SWIG 自动生成 dynamic_cast 代码。这似乎是一个比第一个更好的解决方案,但是在更深入的研究中,它仍然需要您寻找所有方法以及它可能返回的所有可能的派生类型。再次,一个巨大的维护问题。我希望我有一个文档链接,但找不到。我通过查看 SWIG 附带的示例代码发现了此功能。
  3. 创建一个 C# 方法来创建派生对象的实例并将 cPtr 传输到新实例。虽然我认为这很笨拙,但它确实有效。请参阅下面的示例。
    public static object castTo(object fromObj, Type toType)    {        object retval = null;        BaseClass fromObj2 = fromObj as BaseClass;        HandleRef hr = BaseClass.getCPtr(fromObj2);        IntPtr cPtr = hr.Handle;        object toObj = Activator.CreateInstance(toType, cPtr, false);        // make sure it actually is what we think it is        if (fromObj.GetType().IsInstanceOfType(toObj))        {            return toObj;        }        return retval;    }

这些真的是选择吗?如果我不愿意深入研究所有现有函数和类派生,那么我就只剩下#3 了吗?任何帮助将不胜感激。

最佳答案

默认 SWIG generates C# and Java code that does not support downcast对于多态返回类型。我找到了解决此问题的直接方法,前提是您的 C++ 代码能够识别返回的 C++ 实例的具体类。也就是说,仅当您使用 SWIG 包装的 C++ API 具有类似于 C# object.GetType() 或 Java Object.getClass() 的内容时,我的技术才有效。

解决方案是添加一个 C# 中间类方法来实例化 C++ 所说的具体类。然后,使用 %typemap(out) 告诉 SWIG 在返回抽象类时使用这个中间类方法。

这是一个非常简洁的解释,所以请参阅我的博客文章,其中显示 how to generate polymorphic C# and Java that you can downcast .它包含所有详细信息。

关于c# - 如何使用 SWIG 生成的接口(interface)在 C# 中正确向下转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2458025/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com