如何使用 swig 将 python 类实例作为 c++ 函数的参数传递?

Posted

技术标签:

【中文标题】如何使用 swig 将 python 类实例作为 c++ 函数的参数传递?【英文标题】:how to pass python class instance as a parameter of c++ fuction using swig? 【发布时间】:2017-10-11 04:43:14 【问题描述】:

我正在尝试使用 swig 将 c++ 类接口翻译成其他语言。 我的 c++ 界面是这样的:

这是文件 mitprotocol.h

class MitProtocolCallBack

public:
    virtual const string & TestFunc(deque<int> & param) = 0;
;

class MitProtocolInterface

public:
    virtual void ReleaseMe() = 0;
    virtual void SetCallBack(MitProtocolCallBack * mitProtocolCallBack) = 0;
    virtual void UnTar(const string & filePathAndName) = 0;
;

MitProtocolInterface * CreateMitProtocolInterface();

在 c++ 中,我可以像这样使用这个接口:

这是文件 test.cpp:

class testclass : public MitProtocolCallBack


public:
    void playhaha()
    
        mitProtocolInterface->UnTar("");
    
private:
    string str_res;

public:
    virtual const string & TestFunc(deque<int> & param)
    
        str_res = "abc";
        return str_res;
    
private:
    MitProtocolInterface * mitProtocolInterface;

public:
    testclass()
    
        mitProtocolInterface = CreateMitProtocolInterface();
        mitProtocolInterface->SetCallBack(this);
    
    ~testclass()
    
        mitProtocolInterface->ReleaseMe();
    
;

void main()

    testclass haha;
    haha.playhaha();

然后我尝试使用 swig 包装 c++ 接口:

这是文件 mitprotocol.i:

%module mitprotocol

%include "std_string.i"

%include "std_deque.i"

%
#include "mitprotocol.h"
%

namespace std 
   %template(IntDeque) deque<int>;


%include "mitprotocol.h"

然后我执行了:

swig -c++ -python mitprotocol.i

然后我得到了 2 个文件:

file mitprotocol.py: for python interface
file mitprotocol_wrap.cxx: to compile with other c++ source codes as a lib

然后我尝试使用python接口:

这是文件 test.py:

import mitprotocol

class myclass(mitprotocol.MitProtocolCallBack):
    def __init__(self):
        self.mitProtocolInterface = mitprotocol.CreateMitProtocolInterface()
        self.mitProtocolInterface.SetCallBack(self)

    def __delete__(self):
        self.mitProtocolInterface.ReleaseMe()

    def TestFunc(self, param):
        print param
        return "aedfas"

    def playhaha(self):
        self.mitProtocolInterface.UnTar("")

ffsa = myclass()
ffsa.playhaha()

最后我遇到了一个错误:

self.mitProtocolInterface.SetCallBack(self)

错误是:

TypeError: in method 'MitProtocolInterface_SetCallBack', 
argument 2 of type 'MitProtocolCallBack *'

我认为它在尝试将 python 类实例传递给 swig 包装的 c++ 接口时崩溃了。有人帮忙吗?

【问题讨论】:

我自己想出来的,请检查这些问题的答案 【参考方案1】:

有两个关键方面:

1.给.i文件添加多态性:

%module(directors="1") mitprotocol

%include "std_string.i";

%include "std_deque.i";

%
#include "mitprotocol.h"
%

namespace std 
   %template(IntDeque) deque<int>;


%feature("director") MitProtocolCallBack;

%include "../../mitprotocol/src/traffic/mitprotocol.h";

2.python应用在初始化时需要调用超类的init:

import mitprotocol

class myclass(mitprotocol.MitProtocolCallBack):
    def __init__(self):
        mitprotocol.MitProtocolCallBack.__init__(self)
        self.mitProtocolInterface = mitprotocol.CreateMitProtocolInterface()
        self.mitProtocolInterface.SetCallBack(self)

    def __delete__(self):
        self.mitProtocolInterface.ReleaseMe()

    def TestFunc(self, param):
        print param
        return "aedfas"

    def playhaha(self):
        self.mitProtocolInterface.UnTar("")

ffsa = myclass()
ffsa.playhaha()

【讨论】:

以上是关于如何使用 swig 将 python 类实例作为 c++ 函数的参数传递?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 SWIG 在 Python 中实例化 C++ 类(获取属性错误)

如何使 python 类满足 SWIG 中的接口?

如何使用 swig C++ 命名空间作为 python 模块公开

如何使用 Python 列表在 C++ 中使用 SWIG 分配 std::vector?

使用 SWIG 将 C++ 文件包装为 Python 文件

如何使用 SWIG 将 C++ 数组转换为 Python 列表?