std_vector.i 未正确包装继承的类

std_vector.i doesn't wrap inherited classes correctly

本文关键字:包装 继承 vector std      更新时间:2023-10-16

在C++中,我有一个类("BaseClass")和一个从BaseClass继承的类("ClassA")。我使用SWIG 3.0.2将我的C++内容包装到C#,并使用"std_vector.I"在我的C#应用程序中启用"List"功能。

在C++函数"CallCS"中,我创建了一个由两个元素组成的列表——第一个是BaseClass类,第二个是ClassA类。该列表通过回调函数提供给C#应用程序。接口文件显示了我如何包装列表。

然而,在C#应用程序中迭代列表时,我无法将ClassA元素作为ClassA元素访问,尽管它肯定是ClassA元素(我根本无法以任何方式强制转换它)。我只能像访问BaseClass对象一样访问它。

有人能告诉我这里有没有遗漏什么吗?

这是我的C++.h文件:

#include <vector>
class BaseClass
{
public:
    int m_x;
    BaseClass(int x): m_x(x) {}
    int GetX() { return m_x; }
};
class ClassA : public BaseClass
{
public:
    int m_y;
    ClassA(int x, int y) : BaseClass(x), m_y(y) {}
    int GetY() { return m_y; }
};
typedef std::vector<BaseClass*> BaseListType;
class Receiver
{
public:
    virtual void CallBack(BaseListType& list) {}
};
class Sender
{
public:
    Receiver* m_receiver;
public:
    Sender(Receiver* receiver) : m_receiver(receiver) {}
    void CallCS()
    {
        BaseListType list;
        list.push_back(new BaseClass(0));
        list.push_back(new ClassA(1, 2));
        m_receiver->CallBack(list);
    }
};

这是我的接口文件:

%module(directors="1") example
%include <std_vector.i>
%feature("director") Receiver;
%{
#include "example.h"
%}
%include "example.h"
%template(BaseListType) std::vector<BaseClass*>;

这是我的C#文件:

using System;
using System.Collections.Generic;
using System.Linq;
public class runme
{
    class Subscriber : Receiver
    {
        public override void CallBack(BaseListType list)
        {
            Console.WriteLine("------------------------ CallBack ...");
            Console.WriteLine("  Expectation:");
            Console.WriteLine("    First elem:  BaseClass");
            Console.WriteLine("    Second elem: ClassA");
            Console.WriteLine();
            var classalist = list.Select(x => x as ClassA).Where(x => x != null).ToList();
            Console.WriteLine("  Count(ClassA) = " + classalist.Count() + ":");
            foreach (BaseClass elem in list)
            {
                Console.WriteLine("    Is BaseClass: " + (elem is BaseClass) + " ... Is ClassA: " + (elem is ClassA));
            }
            Console.WriteLine("------------------------ CallBack done");
        }
        public void Run() 
        {
            Sender s = new Sender(this);
            s.CallCS();
        }
    }
    static void Main() 
    {
        Subscriber s = new Subscriber();
        s.Run();
    }
}

无法在此处进行测试,但将virtual ~BaseClass() {}添加到BaseClass可能会完成此操作。