SWIG:自定义类的对象作为输出参数(使用Python)

时间:2014-02-18 09:24:51

标签: swig

(这是我昨天问过的一个问题,但我对其进行了简化)

我创建了一个类,其中我想要两个对象作为函数的输出参数(以下称为Test)。但是当我运行swig命令swig -c ++ -python swigtest.i时,我收到错误“警告453:无法应用(MyClass& OUTPUT)。没有定义任何类型图。”我尝试添加类型图,但这没有帮助。我也尝试使用指针,指针指针和指针引用,这也无济于事。

我觉得我忽略了一些简单的事情,因为这应该是很常见的事情。或者我是否需要编写一个复杂的类型图,就像我已经看过但不明白(还)?

以下是我的代码:

MyClass.h(简化使其易于理解,因此只切换到int无效):

class MyClass
{
    int x;
public:
    int get() const
    {
        return x;
    }
};

void Test(MyClass &obj1, MyClass &obj2);

swigtest.i:

%module swigtest

%include typemaps.i

%{
#define SWIG_FILE_WITH_INIT
%}

%{
#include "MyClass.h"
%}

%include "MyClass.h"

%apply (MyClass& OUTPUT)  { MyClass &obj1 }
%apply (MyClass& OUTPUT)  { MyClass &obj2 }

3 个答案:

答案 0 :(得分:1)

正如我之前的评论所述,%apply OUTPUT技巧仅适用于一组有限的POD类型。

对于未来的Swiggers,这个解决方案对我有用(在C#绑定中):

%typemap(cstype) CustomType* "out CustomType"
%typemap(csin,
   pre="    $csclassname temp$csinput = new $csclassname();",
  post="    $csinput = temp$csinput;"
) CustomType* "$csclassname.getCPtr(temp$csinput)"

这将生成一个带有" out"的公共接口。由指针传递的CustomType的参数。内部P / Invoke接口(csim)保留为原始指针。 " csin" typemap创建一个临时变量并分配给输出参数。

另外值得注意的是,在C#中,如果MyCustomType已经是引用类型,您可能不需要它,但是如果有一个修改参数值的API而不将其声明为" out&#则很奇怪34; (这实际上适用于我的类型,但我更喜欢显式的param)。

答案 1 :(得分:0)

尝试:

%module swigtest

%{
#define SWIG_FILE_WITH_INIT
#include "MyClass.h"
%}

%include "typemaps.i"
%apply MyClass *OUTPUT { MyClass &obj1, MyClass &obj2 };

%include "MyClass.h"

您还可以创建一个返回std :: list的包装器:

%include "std_list.i"
%ignore Test;
%rename(Test) TestWrap;
%inline %{
     std::list<MyClass> TestWrap() {
           MyClass obj1, obj2;
           Test(obj1, obj2);
           std::list<MyClass> tempList;
           tempList.push_back(obj1);
           tempList.push_back(obj2);
           return tempList;
     }
%}

答案 2 :(得分:0)

我决定在swigtest.i中添加额外的Python代码来包装测试函数,以便我可以编写obj1, obj2 = Test2()。我仍然认为必须有一个更容易的解决方案,

// swigtest.i:

%module swigtest

%{
#define SWIG_FILE_WITH_INIT
#include "MyClass.h"
%}

%include "MyClass.h"

%insert("python") %{
    def Test2():
        obj1 = swigtest.MyClass()
        obj2 = swigtest.MyClass()
        swigtest.Test(obj1, obj2)
        return obj1, obj2
%}