Windows平台搭建Swig环境示例,并且解决python无法返回double类型的问题

1. Windows下安装Swig

详情参考 https://blog.csdn.net/aganliang/article/details/91129379

2. 新建test.cpp文件

#include "test.h"

int addReturnInt(int a, int b)
{
	return a + b;
}

void addPointerDouble(double& a, double& b, double& res)
{
	res = a + b;
}

新建test.h文件

#ifndef TEST_H
#define TEST_H

int addReturnInt(int a, int b);

#ifdef SWIG
%apply double& INPUT{ double& a }
%apply double& INPUT{ double& b }
%apply double& INOUT{ double& res }
#endif
void addPointerDouble(double & a, double & b, double & res);

#endif

新建test.i文件

%module TestSwig
%{
#include "test.h"
%}
%include "test.h"

将这三个新建的文件放入一个文件夹中

3. 打开cmd命令行 cd进刚刚创建的文件夹内

执行swig命令

swig -c++ -python  test.i

执行完毕后,会在当前目录下生成一个名为test_wrap.cxx的文件以及TestSwig.py文件

4. 打开VS,新建一个C++空项目(控制台)

在菜单栏(正上方)设置为release x86, 将cxx文件,h文件,cpp文件添加进项目中

5. python环境配置:

  • 配置改为Release x86
  • 配置属性->常规->Windows SDK版本修改为【10.0.18362.0】或【最新安装版本】
  • 配置属性->常规->配置类型修改为【动态库(.dll)】
  • 配置属性->高级->目标文件扩展名修改为【.pyd】
  • 配置属性->C/C++->常规->附加包含目录->添加【D:\anconda\envs\py36\include】
  • 配置属性->VC++目录->库目录->添加【D:\anconda\envs\py36\libs】(即为python36.lib所在路径)
  • 配置属性->连接器->输入->附加依赖项->添加【python36.lib】

6. VS编译项目,点击生成选项,会在配置的输出目录中生成TestSwig.pyd文件。生成完毕之后将此文件重命名为_TestSwig.pyd(原因:与刚刚swig生成的py文件重名了,不利于调用)

7. 将pyd文件与生成的py文件放在同一个目录下

执行测试代码:

import TestSwig

a = 1
b = 2
res = TestSwig.addReturnInt(a, b)
print('原生C++ int 返回:', type(res), res)

print('-------------------------')

a1 = 1.0
a2 = 2.0
res = 0.0

# 这里的res是通过swig编译脚本里的INOUT关键字返回
res = TestSwig.addPointerDouble(a1, a2, res) 的
print('原生C++ double 引用返回:', type(res), res)

执行结果:

原生C++ int 返回: <class 'int'> 3
-------------------------
原生C++ double 引用返回: <class 'float'> 3.0

至此,python就可以调用c++封装的函数了


总结:

test.h中的swig宏是解决python类型中没有double类型返回的关键

#ifdef SWIG
%apply double& INPUT{ double& a }
%apply double& INPUT{ double& b }
%apply double& INOUT{ double& res }
#endif

其中:% 与apply不能分离(这个巨坑,别问我怎么知道的)
参数与函数保持一致,如果函数入参为int这种非引用、指针类型的,可以不写入SWIG宏内
INPUT代表输入输出,编译后的python得出结果需要返回(因为python没有显式的使用指针)
OUTOUT代表输出,只能在python内return出结果
INPUT代表输入,只能通过python赋值给C++函数参数

更新:使用c++ class风格的swig封装

头文件test.h:

#ifndef TEST_H
#define TEST_H

class ClassTest
{
public:
	ClassTest();
	~ClassTest();
	int addReturnIntCpp(int a, int b);

	#ifdef SWIG
	%apply double& INPUT{ double& a }
	%apply double& INPUT{ double& b }
	%apply double& INOUT{ double& res }
	#endif
	void addPointerDoubleCpp(double& a, double& b, double& res);
};
#endif

类文件test.cpp:

#include "test.h"

ClassTest::ClassTest(){}
ClassTest::~ClassTest() {}

int ClassTest::addReturnIntCpp(int a, int b)
{
	return a + b;
}

void ClassTest::addPointerDoubleCpp(double& a, double& b, double& res)
{
	res = a + b;
}

i文件同上,编译方式同上。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值