用SWIG来生成Qt C++动态库的Python绑定

转载:

https://codeantenna.com/a/pdQUKXTlSI

环境如下

  • Windows XP
  • Python 2.7.2
  • Qt SDK 4.8.4
  • MinGW (gcc 4.4.0)
  • SWIG 2.0.9

下载SWIG

  • 下载网址 https://sourceforge.net/projects/swig/files/swigwin/
  • 直接下载它的zip包: swigwin-2.0.9.zip, 解压之后就可以用了

目标

  1. 使现有的Qt C++动态链接库能被Python调用。而且
  2. 不能重新编译该动态链接库

目前我们有该库的头文件(bar.h),库文件(libbar.a, bar.dll)

问题和方法

既然我们不能修改bar.dll库的代码,那么我们只能写一个C++ Wrapper 类来包装bar.dll,SWIG可以把这个Wrapper类绑定成Python库。

生成动态链接库bar.dll

首先我们来生成下面要用到的动态库bar.dll. 我们会用到文件bar.h, bar.cpp, bar.pro

  • bar.h
#ifndef BAR_H
#define BAR_H

#if defined(BAR_LIBRARY)  
    #define BARSHARED_EXPORT __declspec(dllexport)  
#else  
    #define BARSHARED_EXPORT __declspec(dllimport)  
#endif

#include <string>
using namespace std;

class QString;

class BARSHARED_EXPORT Bar {
public:
    Bar();
    ~Bar();
    int len(const QString &str);
};

#endif // BAR_H
  • bar.cpp
#include <QString>
#include "bar.h"


Bar::Bar()
{
}
Bar::~Bar()
{
}

int Bar::len(const QString &str)
{
    return str.size();
}
  • bar.pro
TEMPLATE = lib
QT       -= gui
DEFINES += BAR_LIBRARY
HEADERS += bar.h
SOURCES += bar.cpp


现在建一个bar目录,把上面三个文件拷到目录里,编译成动态库(libbar.a, bar.dll)。

D:\GitHub\exercise\swig>cd bar
D:\GitHub\exercise\swig\bar>qmake
D:\GitHub\exercise\swig\bar>make release

生成的库文件应该在bar\release目录下了。

D:\GITHUB\EXERCISE\SWIG\BAR
│  bar.cpp
│  bar.h
│  bar.pro
│  bar.pro.user
│  Makefile
│  Makefile.Debug
│  Makefile.Release
│  test.cpp
│
├─debug
└─release
        bar.dll
        bar.o
        libbar.a
        test.o

用SWIG生成Python绑定

现在我们写一个Wrapper类BarBinding来调用Bar.

//barbinding.h

#ifndef BARBINDING_H
#define BARBINDING_H

#include<string>

using namespace std;

class Bar;
class BarBinding
{
public:
    BarBinding();
    ~BarBinding();
    int len(const string &str);
private:
    Bar *p;
};

#endif // BARBINDING_H

这里注意barbinding.h头文件里没有用任何Qt相关的类。SWIG目前没有提供对Qt类的直接支持,所以,我们用C++标准类string来代替QString.

//barbinding.cpp

#include <QString>
#include "barbinding.h"
#include "bar.h"

BarBinding::BarBinding()
{
    p = new Bar();
}

BarBinding::~BarBinding()
{
    if (p) {
        delete p;
        p = NULL;
    }
}

int BarBinding::len(const string &str)
{
    if (p) {
        QString s(str.c_str());
        return p->len(s);
    } else {
        return -1;
    }
}

接着写一个SWIG的接口文件bar.i来描述我们需要绑定到Python的那些类和方法。基本上bar.i就是对barbinding.h头文件的一个详细描述。

/* File : bar.i */
%module bar

%include "std_string.i"
using namespace std;

%{
#include "barbinding.h"
%}

/* Let's just grab the original header file here */
%include "barbinding.h"

运行SWIG来生成绑定用的C++和python文件

D:\GitHub\exercise\swig\bar>D:\swigwin-2.0.9\swig.exe -python -c++ bar.i

现在bar目录下多了如下两个文件


接着运行如下的.pro文件生成最后的绑定

TEMPLATE = lib
QT       -= gui

TARGET = _bar

INCLUDEPATH += $$PWD \
    D:/Python27/include

HEADERS += barbinding.h

SOURCES += barbinding.cpp \
	bar_wrap.cxx

LIBS += -L$$PWD/release -lbar -LD:/Python27/libs -lpython27

D:\GitHub\exercise\swig\bar>qmake barbinding.pro

D:\GitHub\exercise\swig\bar>make  release

现在bar\release目录下就生成了我们需要的python绑定"_bar.dll". 


我们需要把“_bar.dll"改名成Python能认识的后缀名"_bar.pyd".此外还要把bar\bar.py拷贝到bar\release\bar.py。

D:\GitHub\exercise\swig\bar>copy bar.py release\bar.py
        1 file(s) copied.
D:\GitHub\exercise\swig\bar>rename release\_bar.dll _bar.pyd

到此我们就完成了对bar.dll库的绑定。release目录下的三个文件(调用关系:bar.py->_bar.pyd->bar.dll)就是用python来调用bar.dll需要的全部东西了。

来试试我们生成的Python绑定

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值