如何在 swig 中包装从 vector 派生的 class

How to wrap a class derived from vector in swig

我想用 swig 将派生自 std::vector 的 class 和一些扩展函数包装到 csharp 中。还需要 vector 中的函数,例如 push_back 以将新项目添加到 class(在 csharp 中命名为 Add)。

我尝试使用 swig 的默认设置,IntArray 在 csharp 中有效。但是,vector 的函数无效。

如果我尝试在 .i 文件中定义向量:

namespace std{
%template(ScalarVec) vector<ScalarTest>; 
}

a class 名为 ScalarVec 的函数类似于 vector 在 csharp 中有效,但没有扩展函数。

如何使用 swig 将 ScalarArray 包装成 csharp?

下面是一个简单的例子

#include <vector>
#include <numeric>
namespace test
{
    struct ScalarTest {
        int val;
    };
    struct ScalarArray : public std::vector<ScalarTest>
    {
        int sum() const { 
            int res = 0;
            for (const ScalarTest &item : *this) {
                res += item.val;
            }
            return res;
        }
    };
}

SWIG 对声明顺序很挑剔。下面正确包装了您的示例代码并可以调用 sum 函数。我没有为 C# 设置,所以演示是为 Python:

创建的

test.i

%module test

%{
// Code to wrap
#include <vector>
#include <numeric>

namespace test
{
    struct ScalarTest {
        int val;
    };
    struct ScalarArray : public std::vector<ScalarTest>
    {
        int sum() const { 
            int res = 0;
            for (const ScalarTest &item : *this) {
                res += item.val;
            }
            return res;
        }
    };
}
%}

namespace test
{
    struct ScalarTest {
        int val;
    };
}

%include <std_vector.i>
// Must declare ScalarTest above before instantiating template here
%template(ScalarVec) std::vector<test::ScalarTest>;

// Now declare the interface for SWIG to wrap
namespace test
{
    struct ScalarArray : public std::vector<ScalarTest>
    {
        int sum() const;
    };
}

demo.py

import test
x = test.ScalarArray()
a = test.ScalarTest()
a.val = 1
b = test.ScalarTest()
b.val = 2
x.push_back(a)
x.push_back(b)
print('sum',x.sum())
print(x[0].val,x[1].val)

输出:

sum 3
1 2