【问题标题】:SWIG: objects of a custom class as output argument (with Python)SWIG:自定义类的对象作为输出参数(使用 Python)
【发布时间】:2014-02-18 09:24:50
【问题描述】:

(这是我昨天问的一个问题,但我简化了它)

我创建了一个类,我希望将其中的两个对象作为函数的输出参数(下面称为 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 }

【问题讨论】:

  • 您应该将您的答案放在单独的答案中,而不是在您的问题中。另外请注意,您可以使用“%ignore Test”,以便将 python 插入命名为“Test”。
  • 对不起,我刚开始在 Stack Overflow 上发帖。我只是按照你的建议做了。
  • 没问题,我们都在这里学习

标签: swig


【解决方案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”类型映射创建一个临时变量并分配给输出参数。

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

【讨论】:

    【解决方案2】:

    试试:

    %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;
         }
    %}
    

    【讨论】:

    • %apply 的重点是让我可以做obj1, obj2 = Test() 而不是obj1 = MyClass() obj2 = MyClass() Test(obj1, obj2) 你的解决方案只允许我做后者。
    • 我正在查看您的问题,但我没有看到您在哪里陈述了这条非常重要的信息!你能用这个更新你的问题吗?我已经编辑了我的答案,也许这次会相关:)
    • 对不起,我认为使用%apply MyClass &amp;OUTPUT 会明确表示我想这样做,我应该更清楚。我尝试了您的解决方案,但不幸的是我仍然遇到同样的错误。
    • 刚刚注意到参数名称是 mc 而不是 obj,我不记得这是否有区别,而且我相信你必须使用指针来返回。我刚刚编辑过,你能再试一次吗?
    • 这行得通,谢谢。但最后我使用了不同的方法,请参阅我编辑的问题。
    【解决方案3】:

    我决定在 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
    %}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-22
      • 2019-04-22
      相关资源
      最近更新 更多