4

编译运行SWIG的example代码样例

 4 years ago
source link: https://note.qidong.name/2018/01/hello-swig-example/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

编译运行SWIG的example代码样例

2018-01-11 18:09:55 +08  字数:1711  标签: Python C

跑通SWIG的example代码,比Boost.Python的HelloWorld要简单一些。 不过,对不熟悉gcc的人来说,还是很费劲。 本文基于官方教程,补充了一个可行的Makefile。

简介

SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。 SWIG能应用于各种不同类型的语言包括常用脚本编译语言例如Perl, PHP, Python, Tcl, Ruby and PHP。 SWIG普遍应用于创建高级语言解析或汇编程序环境,用户接口,作为一种用来测试C/C++或进行原型设计的工具。 SWIG还能够导出XML或Lisp s-expressions格式的解析树。 SWIG可以被自由使用,发布,修改用于商业或非商业中。

以上是官网的中文版介绍摘要。

SWIG其实是通过*.i文件,声明一些接口(interface),自动生成一个*_wrap.c和一个*.py文件。 *_wrap.c文件参与C/C++层的编译,一起生成_*.so文件,而*.py文件则作为上层Python的使用接口。 其价值在于,新增了一个抽象层级,令使用更便捷,而且其中的代码都是自动生成的。

在官网上的Tutorial过于老旧,其实不能成功跑起来,只是胜在简洁。 真正可用的教程在《SWIG and Python》,与时俱进,略有优化。

代码样例

example.c

#include <time.h>

double My_variable = 3.0;

int fact(int n) {
  if (n <= 1) return 1;
  else return n*fact(n-1);
}

int my_mod(int x, int y) {
  return (x%y);
}

char *get_time()
{
  time_t ltime;
  time(&ltime);
  return ctime(&ltime);
}

以上是example.c文件,是需要在Python中使用的代码样例。 其中包括一个全局变量与三个函数。

test.py

为了简化,以打印作为测试手段。

import example

print('My_varaiable: %s' % example.cvar.My_variable)
print('fact(5): %s' % example.fact(5))
print('my_mod(7,3): %s' % example.my_mod(7,3))
print('get_time(): %s' % example.get_time())

以上是test.py,是希望如何使用C语言代码的样例。 函数可以直接调用,基本数据类型会自动转换。 全局变量则需要在example.cvar中调用。

example.h

#ifndef EXAMPLE_H
#define EXAMPLE_H

extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();

#endif

以上是example.h文件。 这个额外的文件不是必须的,只是用来展示interface文件的一些区别。

example.i

%module example

%{
#include "example.h"
%}

extern double My_variable;
extern int fact(int n);
extern int my_mod(int x, int y);
extern char *get_time();

以上是example.i文件。

  • %module指定了模块名为example
  • %{}%则指定了在生成的example_wrap.c文件中需要的声明,这里用了一个example.h文件。 如果换成下面的四行extern,在这个Demo里也是等效的。
  • extern的四行,声明了需要对外暴露的四个接口。
  • 除了%部分,其它均遵循.h文件的语法。
  • 虽然example.h的内容和四个extern几乎是一致的,而且%{}%中也可以直接使用extern,但第三部分不能使用#include

编译准备

build-essential以外,还需要准备python-devpython3-dev。 当然,swig的可执行程序也是必须安装的。

sudo apt install swig python3-dev

(本文创作平台是Debian Stretch,SWIG的版本是3.0.10-1.1。 Python的库是python2.7和python3.5m。)

编译

编译前,需要把example.i文件转换成example_wrap.cexample.py两个文件。

swig -python example.i

转换完成后,即可使用gcc进行编译。 以下为一个Makefile样例。

_example.so : example.o example_wrap.o
	gcc -shared example.o example_wrap.o -o _example.so -lpython3.5m

example.o : example.c
	gcc -c -fPIC -I/usr/include/python3.5m example.c

example_wrap.o : example_wrap.c
	gcc -c -fPIC -I/usr/include/python3.5m example_wrap.c

example_wrap.c example.py : example.i example.h
	swig -python example.i

clean:
	rm -f *.o *.so example_wrap.* example.py*

test:
	python3 test.py

all: _example.so test

.PHONY: clean test all

.DEFAULT_GOAL := all

在添加了这个Makefile后,执行make即可自动转换interface、编译、执行测试,从命令行看到显示结果。

$ make
python3 test.py
My_varaiable: 3.0
fact(5): 120
my_mod(7,3): 1
get_time(): Thu Jan 11 17:56:45 2018

对于C++文件,除了-python参数外,还需加上-c++。 编译时,也需使用g++。 对Python 2.7来说,需要把相关信息做出替换(3.5m换成2.7python3换成python2)。

注意*.so文件的名称是_example.so一定要有下划线

这里的坑,都被孤踩过了,最后汇聚成这个Makefile。 如果还有其它隐藏坑,可以在搜索前仔细阅读《31.2.5 Using your module》。

参考

SWIG在GitHub上的项目主页:https://github.com/swig/swig


Recommend

  • 22
    • www.cnblogs.com 4 years ago
    • Cache

    JAVA各种OOM代码样例及解决方法

    周末了,觉得我还有很多作业没有写,针对目前大家对OOM的类型不太熟悉,那么我们来总结一下各种OOM出现的情况以及解决方法。 我们把各种OOM的情况列出来,然后逐一进行代码编写复现和提供解决方法。 1. 堆溢出-java.lan...

  • 7
    • note.qidong.name 4 years ago
    • Cache

    在setup.py中配置SWIG模块

    在setup.py中配置SWIG模块 2018-03-20 16:17:05 +08  字数:1883  标签: Python C

  • 8
    • note.qidong.name 4 years ago
    • Cache

    用SWIG向Python提供C++里STL的容器

    用SWIG向Python提供C++里STL的容器 2018-03-06 18:10:30 +08  字数:1226  标签: Python

  • 12
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    C++生产者与消费者多线程样例

    点击上方蓝字可直接关注!方便下次阅读。如果对你有帮助,麻烦点个在看或点个赞,感谢~        文章首发   ...

  • 6
    • abcdxyzk.github.io 4 years ago
    • Cache

    字符设备驱动和等待队列样例

    字符设备驱动和等待队列样例 2015-05-21 15:58:00 前两篇的样例 字符设备驱动程序

  • 4
    • zhouj000.github.io 4 years ago
    • Cache

    支付系统(一) 架构样例

    ZhouJ000 Blog银行技术架构(一) 支付清算体系 银行技术架构(二) 业务模式与银行账户

  • 6
    • help.dreamhost.com 3 years ago
    • Cache

    How to install a newer version of SWIG

    How to install a newer version of SWIG Overview To run the commands in this article, you must log into your server via SSH with your Shell user. View the following articles f...

  • 4
    • www.blogjava.net 3 years ago
    • Cache

    SPRING REACTOR 使用样例

    SPRING REACTOR 使用样例 SpringReactorTest.javapackage com.paul.testreactivestream.reactor;import java.util.List;import ...

  • 6
    • hkvision.cn 3 years ago
    • Cache

    SWIG 以Python为例

    本文为原创文章,转载注明出处,欢迎关注网站https://hkvision.cnSWIG用途SWIG是用于开发C/C++与Java,Python,Perl,C#等高级语言之间接口的框架,利用这个框架,我们可以很方便...

  • 8

    本文为原创文章,转载注明出处,欢迎关注网站https://hkvision.cn先允许我吐槽一下海康威视的SDK有多难用SWIG编译先声明我编译的是linux版本的,环境是ubuntu 18.04,还没有开始做...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK