SWIG 多语言接口变换 【转】

一.             SWIG 是Simple Wrapper and Interface Generator的缩写,是一个帮助使用C或者C++编写的软件创建其他编语言的API的工具。例如,我想要为一个C++编写的程序创建.NET API,一般情况下我必须使用托管C++(Managed C++)去编写大量的代码才能生成它的.NET API。有了SWIG,这个机械的工作将变得非常简单。你只须要使用一个接口文件告诉SWIG要为那些类创建.NET API,SWIG就会自动帮你生成它的.NET API。

当 然,SWIG不仅仅支持创建.NET API。最新版本的SWIG支持常用脚本语言Perl、PHP、Python、Tcl、Ruby和非脚本语言C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML以及R,甚至是编译器或者汇编的计划应用(Guile, MzScheme, Chicken)。也就是说可以用Swig将C++接口封装为java等语言可以调用的形式。

二.             环境搭建

1.       下载swigwin,在E:/lib目录下解压,即把swig安装到E:/lib/swig目录中。

2.       新建一个Win32 Console Application,注意在Application Settings中选择DLL以及空项目。完成后将工程的配置改成release

3.       工具 —> 选项 —> 项目和解决方案 —> VC++目录 —> 添加E:/lib/swigwin。即把swig添加到VC的可执行目录。

----------------若封装成Python可用的API,执行如下步骤----------------------------

4.       下载python2.5,安装到D:/Program Files目录,并在环境变量PATH中加入D:/Program Files/python2.5。

5.       把D:/Program Files/python2.5/include加入VC的Include路径,将D:/Program Files/python2.5/libs加入VC的Library路径。

-----------------若封装成Java可用的API,执行如下步骤--------------------------------

6.       下载JDK,安装到D:/Program Files目录,并在环境变量PATH中加入D:/Program Files/Java/jdk1.6.0_10/bin(如果之前安装过Oracle,要将D:/Program Files/Java/jdk1.6.0_10/bin放在Oracle/jre/1.3.1/bin前面,否则在编译的时候默认会选择oracle的 jdk)

7.       把D:/Program Files/Java/jdk1.6.0_10/include/win32 和 D:/Program Files/Java/jdk1.6.0_10/include 加入到加入VC的Include路径。

三.             接口文件

要在C/C++工程中创建***.i 的接口文件,告诉SWIG要为那些类的那些方法创建API。

接口文件注解:

1.  模块名由指定的%module来给出(或者用-module命令行选项).这段指示性文字必须写在文件的头部并且在使用时将这个模块名作为扩展模块对象来 使用(此外,这个模块名经常在目标语言中被定义成一个命名空间来使用)。如果模块名在命令行已经被给出了,系统将不考虑由%module标示的模块名了。

对于python:module的名字指定了生成文件xxx.py的xxx名字,

对于java:module的名字指定了生成文件xxx.java的xxx名字

2.  所有在%{...%}块内的东西将被简单作为结果逐字拷贝到SWIG创建的wrapper(包装)文件中。这部分大部分被用来包括头文件和生成 wrapper代码需要的其它声明。这里很重要的强调一点因为你在一个SWIG的输入文件中包含了一个声明,这个声明并不自动显示在生成的wrapper 代码中,因此你需要确信你确实把正确的头文件在%{ ... %}部分中。这里应该指出SWIG不解析和解释附在%{ ... %}部分的文字。SWIG的%{...%}内的语法和语义很类似于输入文件中的声明部分 。

3.  如果打算为类中所有方法创建API,那么有一个非常简单的办法,在接口文件的类声明部分使用%include标记。SWIG将对%include所指定的文件进行语法分析,类中所有公有方法(Public Method)都将在API中暴露。

/* SwigTest.i */

%module SwigTest

%{

#include "SwigTest.h"

%}

%include “SwigTest.h”   //不要和#用混

-------------------------- swig库模块访问部分标准C++库包括STL的方法-------------------

SWIG对于一些语言模块的支持使较全面的但是对很少用到的库则支持的很少。
下面就是表示了C++类和支持的C++库 以及SWIG接口文件的对应表
C++ class                C++ Library file              SWIG Interface library file
std::deque                     deque                                  std_deque.i
std::list                           list                                       std_list.i
std::map                        map                                     std_map.i
std::pair                        utility                                    std_pair.i
std::set                          set                                       std_set.i
std::string                      string                                   std_string.i
std::vector                     vector                                 std_vector.i

因此,当C / C++代码中用到这些库时,可将swig对应的接口文件添加到自己的接口文

件中。如:%include "std_string.i",

库文件完全识别C++的命名空间。如果你输出std::string 或 将它重命名为另一种类型。请确认你将此重命名声明包含到了你的接口文件中。例如:
%module example
%include "std_string.i"

using namespace std;
typedef std::string String;
...
void foo(string s, const String &t);     // std_string typemaps still applied


封装java调用的api且传递的参数中含有中文时,由于c++中的String是使用单字节编码,而java中String是使用Unicode编码,
所以为了传递时不出现乱码,可以包含%include
"std_wstring.i",因为wstring使用的是wchar_t类型,这是宽字符,用于满足非ASCII字符的要求,例如Unicode编
码。

当封装python调用的api且传递的参数中含有中文时,就不用考虑这个编码问题,可以直接使用c++中的String。

四.             编译模块

1.写接口执行命令


了接口文件以后要对接口文件进行编译,右键点击接口文件,修改它的属性,使用自定义编译工具(Custom Build
Tool),命令行(Command Line)内容为swig.exe -c++ -python SwigTest.i
,输出(Outputs)为$(InputName)_wrapper.cpp;

echo JAVA_INCLUDE: %JAVA_INCLUDE%

echo JAVA_BIN: %JAVA_BIN%

echo on

swig.exe -c++ -python SwigTest.i

命令行参数说明:


为了编译java
或python模块,必须包含它们的include和bin目录,可以在PATH中设置JAVA_INCLUDE、JAVA_BIN、
PYTHON_INCLUDE、PYTHON_BIN等,其中include可以在工程属性中设置,如果工程属性中已经设置好,此处不用再包含头两句。

②“ swig.exe ”表示调用你安装的swig的可执行文件,之前已经将其目录加入到VC的可执行目录中,所以此处就可以不用再写路径,否则要找到swig路径才行。

③ “-c++” 表示要封装C++代码(不写默认是封装C代码),

④“-python”表示要封装成Python接口(Swig还可以封装成Java、Ruby等接口),

⑤ “$(InputName)_wrapper.cpp”表示指定要生成的C++代码文件的名字。

swig的命令还有其他的一些,目前用到的如 –package命令,用法可以为:

swig -java -package com.swig -outdir com/swig example.i

在生成java的api时,这个命令使生成的java文件包含在某个包中。

2.编译(右键点击接口文件—>编译)

对于生成python可用的API:执行上述命令会生成两个新的文件,一个是SwigTest.py,一个是SwigTest_wrapper.cpp。

对于生成java可用的API:执行上述命令会生成Java类文件:SwigTestJNI.java,SwigTest.java

和c文件SwigTest_wrapper.cpp。

3.将xxx_wrapper.cpp加入到工程

4.修改工程属性:

-----------------------封装java可用的api---------------------

LinkeràGeneralàOutput File改成SwigTest.dll

Build EventsàPost-Build EventàCommand Line改成:

echo on

"%JAVA_BIN%/javac" *.java

这个命令作用是编译完后调用javac将当前编译路径下的所有.java文件编译成.class二进制文件。

-----------------------封装python可用的api---------------------

LinkeràGeneralàOutput File改成_SwigTest.pyd(注意一定要有下划线)

还有一些配置在VC2005里是默认的,但在VC2003里不是的,请引起注意,包括

① C/C++àCode GenerationàRuntime Library要选择Multi-threaded DLL (/MD)

② C/C++àLanguageàTreat wchar_t as Built-in Type要选择yes(如果转换不涉及wchar等,则无需处理这一项)

③ C/C++àLanguageàEnable Run-Time Type Info要选择yes

5.生成工程

五.利用生成的api就可以在对应的脚本语言(java、python等)中使用啦。

windows环境2.0.7版:http://prdownloads.sourceforge.net/swig/swigwin-2.0.7.zip

时间: 2024-11-13 07:58:01

SWIG 多语言接口变换 【转】的相关文章

Android ndk开发swig编译jni接口配置文件(二)

之前写过一篇Android ndk开发swig编译jni接口.看这篇看不懂,看以去看看.c++与Java有些语言结构还是有一定区别,比如c++结构体,一些函数的返回值等都是有所不同,进行swig编译要进行一些预处理,也就是配置一下就行.下面说说几种情况. 一.一般情况下string,数组,枚举类型等配置Unix.i %module Survey %include "std_string.i" %include "arrays_java.i" %include &qu

使用SWIG将C++接口转换成Java接口

以C++类classifier为例,文件保存于百度网盘 https://pan.baidu.com/s/1c2AwhaS(需密码) 系统:Ubuntu 15.04 参考资料: ubuntu源码安装swig 利用swig转换C++接口到Java接口 SWIG3.0说明文档 编程中出现的错误: java编译时出现undefined symbol:... 此种情况大部分原因是需要在原来的C++库中添加链接某lib....so文件(undefined symbol: _ZN5boost6system15

opencv的C语言接口和C++接口差别(入门篇)

opencv是一个开源的图像处理库,最经典的1.0版本号提供的接口都是C语言接口. 后来的opencv2.x版本号保留了C语言接口,可是提供了C++接口,当中的C语言接口仅仅是为了向后兼容,而C++接口才是大势所趋. 那么这两者有什么差别呢?今天介绍一下配置过程中的差别. 以opencv2.3.0和vs2008为例.配置时.先要配置包括文件和库文件,然后在系统变量path中加入dll文件.最后再项目属性中加入附加依赖库.我平时用的功能不多.一般加入这几项opencv_core230.lib.op

Swift中对C语言接口缓存的使用以及数组、字符串转为指针类型的方法

由于Swift编程语言属于上层编程语言,而Swift中由于为了低层的高性能计算接口,所以往往需要C语言中的指针类型,由此,在Swift编程语言刚诞生的时候就有了UnsafePointer与UnsafeMutablePointer类型,分别对应为const Type*类型与Type *类型. 而在Swift编程语言中,由于一般数组(Array)对象都无法直接用于C语言中含有指针类型的函数参数(比如:void*),所以往往需要将数组转为指针类型,此外也需要将数组中元素内容存放到连续的存储空间.此外,

[转]SQLITE3 C语言接口 API 函数简介

SQLITE3 C语言接口 API 函数简介 说明:本说明文档属作者从接触 SQLite 开始认识的 API 函数的使用方法, 由本人翻译, 不断更新. /* 2012-05-25 */ int sqlite3_open( const char* filename, /* 数据库文件名, 必须为 UTF-8 格式 */ sqlite3** ppDB /* 输出: SQLite 数据库句柄 */ ); 说明: 该函数打开由 filename 指定的数据库, 一个数据库连接句柄由 *ppDB 返回(

Go 语言接口

Go 语言接口 Go 语言提供了另外一种数据类型即接口,它把所有的具有共性的方法定义在一起,任何其他类型只要实现了这些方法就是实现了这个接口. 实例 1 /* 定义接口 */ 2 type interface_name interface { 3 method_name1 [return_type] 4 method_name2 [return_type] 5 method_name3 [return_type] 6 ... 7 method_namen [return_type] 8 } 9

opencv的C语言接口和C++接口区别(入门篇)

opencv是一个开源的图像处理库,最经典的1.0版本提供的接口都是C语言接口.后来的opencv2.x版本保留了C语言接口,但是提供了C++接口,其中的C语言接口只是为了向后兼容,而C++接口才是大势所趋.那么这两者有什么区别呢?今天介绍一下配置过程中的区别. 以opencv2.3.0和vs2008为例,配置时,先要配置包含文件和库文件,然后在系统变量path中添加dll文件,最后再项目属性中添加附加依赖库.我平时用的功能不多,一般添加这几项opencv_core230.lib,opencv_

python调用C语言接口

python调用C语言接口 注:本文所有示例介绍基于linux平台 *** 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题,用C/C++写的底层库,怎么样直接被python来调用? python作为一门胶水语言,当然有办法来处理这个问题,python提供的方案就是ctypes库. ctypes ctypes是python的外部函数库,它提供了C语言的兼容类型,而且可以直接调用用C语言封装的动态库. 如果各位有较

浅入浅出 Go 语言接口的原理

浅入浅出 Go 语言接口的原理 接口是 Go 语言的重要组成部分,它在 Go 语言中通过一组方法指定了一个对象的行为,接口 interface 的引入能够让我们在 Go 语言更好地组织并写出易于测试的代码.然而很多使用 Go 语言的工程师其实对接口的了解都非常有限,对于它的底层实现也一无所知,这其实成为了我们使用和理解 interface 的最大阻碍. 在这一节中,我们就会介绍 Go 语言中这个重要类型 interface 的一些常见问题以及它底层的实现,包括接口的基本原理.类型断言和转换的过程