文件管理 · 2022年8月16日

swigi文件编写|android 怎么使用swig

㈠ python调用swig的问题,如何把‘!=’wrap起来。只是简单的代替

我没用过swig,一直是用boost::python来封装c++的。猜测这个问题是因为swig中没法对重载操作符函数进行直接封装。可否将operator!=直接封装成python对象的__ne__()方法。__ne__()是python对象内嵌的“不等”操作符函数。如果是boost::python的话,应该可以直接这样做,不知道swig里可行不可行。

㈡ 如何在gnuradio中编写自己

虽然gnuradio给我们提供了近百种常用的功能模块block,但是在我们自己的系统设计中,需要不同的模块完成特定的功能,这样就需要我们自己来编写C++源代码,生成新的block以供系统调用。如果源代码、编译文件都要自己编写,需要很强的专业知识,对于我这样的初学者来说费时费力。网上有很其他的方法,如利用模板、下载现成的脚本等等。自己参照的官方网站上的教程,通过gr-modtool这个脚本辅助工具完成了一个简单模块从编写到导入gnuradio-companion的全过程。 首先到htt p s:/ /githu b.co m/mbant/gr-modtool下载gr-modtool。解压之后得到一个gr-modtool-master的文件夹,并将此路径添加到系统的PATH中。进入你想要建立模块的目录,这里以在:/home/jim/code[jim是我的用户名]路径下建立howto_square_ff模块为例,进入目的路径,然后在终端里输入 gr_modtool.py create howto这样就生成了一个名为gr-howto的文件夹以及一个模块的目录结构。 接下来就是编写C++源代码。我们需要写一个.h的头文件,一个.cc的源代码,并分别修改include/CMakeLists.txt和lib/CMakeLists.txt。这些要生成的文件和修改的内容都可以通过gr-modtool来自动帮我们完成。先进入刚才生成的gr-howto文件夹,在终端输入 gr_modtool.py add -t general square_ff显示如下[中间需要输入一个回车,以及两次n]GNU Radio mole name identified: howtoCode is of type: generalBlock/code identifier: square_ffFull block/code identifier is: howto_square_ffEnter valid argument list, including default arguments: Add Python QA code? [Y/n] nAdd C++ QA code? [Y/n] nTraversing lib…Adding file 'howto_square_ff.h'…Adding file 'howto_square_ff.cc'…Traversing swig…Editing swig/howto_swig.i…Traversing python…Editing python/CMakeLists.txt…Traversing grc…Adding file 'howto_square_ff.xml'…Editing grc/CMakeLists.txt…接下来我们就可以按照提供的例程打开相应的.h和.cc文件进行修改。sourc e:g r-howto-write-a-block/include/ho wto_square_ff.hsourc e:g r-howto-write-a-block/lib/ho wto_square_ff.cc 整个模块的目的是对输入的数据进行平方运算。为此还需要写一个验证程序并修改相应的CMakeLists.txt文件。在python目录下添加一个新的名为qa_howto.py的文件。内容参见例程。并对CMakeLists.txt进行如下修改include(GrTest)set(GR_TEST_TARGET_DEPS gnuradio-howto)set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)GR_ADD_TEST(qa_howto ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_howto.py) 最后的工作就是生成模块并安装到gnuradio-companion中。进入gr-howto目录,在终端输入cmake ./,然后输入make,即生成了模块。接着输入make test,如果全部通过测试,则证明模块生成成功。如果想在gnuradio-companion中使用自己的模块,还必须在grc目录下生成xml文件。在终端输入 gr-modtool.py makexml square_ff 打开xml文件并参照例程进行修改。source:gr-howto-write-a-block/grc/howto_square_ff.xml最后回到gr-howto目录,输入sudo make install即可安装。输入gnuradio-companion即可看到你自己生成的模块。至此全部过程结束。 gr-modtool这个脚本为我们编写自己的数字信息处理模块提供了很大的方便,如果想清楚的知道每一部分的作用,可能还要一点点的手动安装,但是对于初学的我来说这个工具是很适用的。

㈢ 如何实现 C/C++ 与 Python 的通信

属于混合编程的问题。较全面的介绍一下,不仅限于题主提出的问题。以下讨论中,Python指它的标准实现,即CPython(虽然不是很严格)本文分4个部分C/C++ 调用 Python (基础篇)— 仅讨论Python官方提供的实现方式Python 调用 C/C++ (基础篇)— 仅讨论Python官方提供的实现方式C/C++ 调用 Python (高级篇)— 使用 CythonPython 调用 C/C++ (高级篇)— 使用 SWIG练习本文中的例子,需要搭建Python扩展开发环境。具体细节见搭建Python扩展开发环境 – 蛇之魅惑 – 知乎专栏1 C/C++ 调用 Python(基础篇)Python 本身就是一个C库。你所看到的可执行体python只不过是个stub。真正的python实体在动态链接库里实现,在Windows平台上,这个文件位于 %SystemRoot%\System32\python27.dll。你也可以在自己的程序中调用Python,看起来非常容易://my_python.c#include <Python.h>int main(int argc, char *argv[]){Py_SetProgramName(argv[0]);Py_Initialize();PyRun_SimpleString("print 'Hello Python!'\n");Py_Finalize();return 0;}在Windows平台下,打开Visual Studio命令提示符,编译命令为cl my_python.c -IC:\Python27\include C:\Python27\libs\python27.lib在linux下编译命令为gcc my_python.c -o my_python -I/usr/include/python2.7/ -lpython2.7在Mac OS X 下的编译命令同上产生可执行文件后,直接运行,结果为输出Hello Python!Python库函数PyRun_SimpleString可以执行字符串形式的Python代码。虽然非常简单,但这段代码除了能用C语言动态生成一些Python代码之外,并没有什么用处。我们需要的是C语言的数据结构能够和Python交互。下面举个例子,比如说,有一天我们用Python写了一个功能特别强大的函数:def great_function(a):return a + 1接下来要把它包装成C语言的函数。我们期待的C语言的对应函数应该是这样的:int great_function_from_python(int a) {int res;// some magicreturn res;}首先,复用Python模块得做‘import’,这里也不例外。所以我们把great_function放到一个mole里,比如说,这个mole名字叫 great_mole.py接下来就要用C来调用Python了,完整的代码如下:#include <Python.h>int great_function_from_python(int a) {int res;PyObject *pMole,*pFunc;PyObject *pArgs, *pValue;/* import */pMole = PyImport_Import(PyString_FromString("great_mole"));/* great_mole.great_function */pFunc = PyObject_GetAttrString(pMole, "great_function");/* build args */pArgs = PyTuple_New(1);PyTuple_SetItem(pArgs,0, PyInt_FromLong(a));/* call */pValue = PyObject_CallObject(pFunc, pArgs);res = PyInt_AsLong(pValue);return res;}从上述代码可以窥见Python内部运行的方式:所有Python元素,mole、function、tuple、string等等,实际上都是PyObject。C语言里操纵它们,一律使用PyObject *。Python的类型与C语言类型可以相互转换。Python类型XXX转换为C语言类型YYY要使用PyXXX_AsYYY函数;C类型YYY转换为Python类型XXX要使用PyXXX_FromYYY函数。也可以创建Python类型的变量,使用PyXXX_New可以创建类型为XXX的变量。若a是Tuple,则a[i] = b对应于 PyTuple_SetItem(a,i,b),有理由相信还有一个函数PyTuple_GetItem完成取得某一项的值。不仅Python语言很优雅,Python的库函数API也非常优雅。现在我们得到了一个C语言的函数了,可以写一个main测试它#include <Python.h>int great_function_from_python(int a); int main(int argc, char *argv[]) {Py_Initialize();printf("%d",great_function_from_python(2));Py_Finalize();}编译的方式就用本节开头使用的方法。在Linux/Mac OSX运行此示例之前,可能先需要设置环境变量:bash:export PYTHONPATH=.:$PYTHONPATHcsh:setenv PYTHONPATH .:$PYTHONPATH2 Python 调用 C/C++(基础篇)这种做法称为Python扩展。比如说,我们有一个功能强大的C函数:int great_function(int a) {return a + 1;}期望在Python里这样使用:>>> from great_mole import great_function >>> great_function(2)3考虑最简单的情况。我们把功能强大的函数放入C文件 great_mole.c 中。#include <Python.h>int great_function(int a) {return a + 1;}static PyObject * _great_function(PyObject *self, PyObject *args){int _a;int res;if (!PyArg_ParseTuple(args, "i", &_a))return NULL;res = great_function(_a);return PyLong_FromLong(res);}static PyMethodDef GreateMoleMethods[] = {{"great_function",_great_function,METH_VARARGS,""},{NULL, NULL, 0, NULL}};PyMODINIT_FUNC initgreat_mole(void) {(void) Py_InitMole("great_mole", GreateMoleMethods);}除了功能强大的函数great_function外,这个文件中还有以下部分:包裹函数_great_function。它负责将Python的参数转化为C的参数(PyArg_ParseTuple),调用实际的great_function,并处理great_function的返回值,最终返回给Python环境。导出表GreateMoleMethods。它负责告诉Python这个模块里有哪些函数可以被Python调用。导出表的名字可以随便起,每一项有4个参数:第一个参数是提供给Python环境的函数名称,第二个参数是_great_function,即包裹函数。第三个参数的含义是参数变长,第四个参数是一个说明性的字符串。导出表总是以{NULL, NULL, 0, NULL}结束。导出函数initgreat_mole。这个的名字不是任取的,是你的mole名称添加前缀init。导出函数中将模块名称与导出表进行连接。在Windows下面,在Visual Studio命令提示符下编译这个文件的命令是cl /LD great_mole.c /o great_mole.pyd -IC:\Python27\include C:\Python27\libs\python27.lib/LD 即生成动态链接库。编译成功后在当前目录可以得到 great_mole.pyd(实际上是dll)。这个pyd可以在Python环境下直接当作mole使用。在Linux下面,则用gcc编译:gcc -fPIC -shared great_mole.c -o great_mole.so -I/usr/include/python2.7/ -lpython2.7在当前目录下得到great_mole.so,同理可以在Python中直接使用。本部分参考资料《Python源码剖析-深度探索动态语言核心技术》是系统介绍CPython实现以及运行原理的优秀教程。Python 官方文档的这一章详细介绍了C/C++与Python的双向互动Extending and Embedding the Python Interpreter关于编译环境,本文所述方法仅为出示原理所用。规范的方式如下:3. Building C and C++ Extensions with distutils作为字典使用的官方参考文档 Python/C API Reference Manual用以上的方法实现C/C++与Python的混合编程,需要对Python的内部实现有相当的了解。接下来介绍当前较为成熟的技术Cython和SWIG。3 C/C++ 调用 Python(使用Cython)在前面的小节中谈到,Python的数据类型和C的数据类型貌似是有某种“一一对应”的关系的,此外,由于Python(确切的说是CPython)本身是由C语言实现的,故Python数据类型之间的函数运算也必然与C语言有对应关系。那么,有没有可能“自动”的做替换,把Python代码直接变成C代码呢?答案是肯定的,这就是Cython主要解决的问题。安装Cython非常简单。Python 2.7.9以上的版本已经自带easy_install:easy_install -U cython在Windows环境下依然需要Visual Studio,由于安装的过程需要编译Cython的源代码,故上述命令需要在Visual Studio命令提示符下完成。一会儿使用Cython的时候,也需要在Visual Studio命令提示符下进行操作,这一点和第一部分的要求是一样的。继续以例子说明:#great_mole.pyxcdef public great_function(a,index):return a[index]这其中有非Python关键字cdef和public。这些关键字属于Cython。由于我们需要在C语言中使用“编译好的Python代码”,所以得让great_function从外面变得可见,方法就是以“public”修饰。而cdef类似于Python的def,只有使用cdef才可以使用Cython的关键字public。这个函数中其他的部分与正常的Python代码是一样的。接下来编译 great_mole.pyxcython great_mole.pyx得到great_mole.h和great_mole.c。打开great_mole.h可以找到这样一句声明:__PYX_EXTERN_C DL_IMPORT(PyObject) *great_function(PyObject *, PyObject *)写一个main使用great_function。注意great_function并不规定a是何种类型,它的功能只是提取a的第index的成员而已,故使用great_function的时候,a可以传入Python String,也可以传入tuple之类的其他可迭代类型。仍然使用之前提到的类型转换函数PyXXX_FromYYY和PyXXX_AsYYY。//main.c#include <Python.h>#include "great_mole.h"int main(int argc, char *argv[]) {PyObject *tuple;Py_Initialize();initgreat_mole();printf("%s\n",PyString_AsString(great_function(PyString_FromString("hello"),PyInt_FromLong(1))));tuple = Py_BuildValue("(iis)", 1, 2, "three");printf("%d\n",PyInt_AsLong(great_function(tuple,PyInt_FromLong(1))));printf("%s\n",PyString_AsString(great_function(tuple,PyInt_FromLong(2))));Py_Finalize();}编译命令和第一部分相同:在Windows下编译命令为cl main.c great_mole.c -IC:\Python27\include C:\Python27\libs\python27.lib在Linux下编译命令为gcc main.c great_mole.c -o main -I/usr/include/python2.7/ -lpython2.7这个例子中我们使用了Python的动态类型特性。如果你想指定类型,可以利用Cython的静态类型关键字。例子如下:#great_mole.pyxcdef public char great_function(const char * a,int index):return a[index]cython编译后得到的.h里,great_function的声明是这样的:__PYX_EXTERN_C DL_IMPORT(char) great_function(char const *, int);很开心对不对!这样的话,我们的main函数已经几乎看不到Python的痕迹了://main.c#include <Python.h>#include "great_mole.h"int main(int argc, char *argv[]) {Py_Initialize();initgreat_mole();printf("%c",great_function("Hello",2));Py_Finalize();}在这一部分的最后我们给一个看似实用的应用(仅限于Windows):还是利用刚才的great_mole.pyx,准备一个dllmain.c:#include <Python.h>#include <Windows.h>#include "great_mole.h"extern __declspec(dllexport) int __stdcall _great_function(const char * a, int b) {return great_function(a,b);}BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved) {switch( fdwReason ) {case DLL_PROCESS_ATTACH:Py_Initialize();initgreat_mole();break;case DLL_PROCESS_DETACH:Py_Finalize();break;}return TRUE;}在Visual Studio命令提示符下编译:cl /LD dllmain.c great_mole.c -IC:\Python27\include C:\Python27\libs\python27.lib会得到一个dllmain.dll。我们在Excel里面使用它,没错,传说中的Excel与Python混合编程:参考资料:Cython的官方文档,质量非常高:Welcome to Cython’s Documentation4 Python调用C/C++(使用SWIG)用C/C++对脚本语言的功能扩展是非常常见的事情,Python也不例外。除了SWIG,市面上还有若干用于Python扩展的工具包,比较知名的还有Boost.Python、SIP等,此外,Cython由于可以直接集成C/C++代码,并方便的生成Python模块,故也可以完成扩展Python的任务。答主在这里选用SWIG的一个重要原因是,它不仅可以用于Python,也可以用于其他语言。如今SWIG已经支持C/C++的好基友java,主流脚本语言Python、Perl、Ruby、PHP、JavaScript、tcl、Lua,还有Go、C#,以及R。SWIG是基于配置的,也就是说,原则上一套配置改变不同的编译方法就能适用各种语言(当然,这是理想情况了……)SWIG的安装方便,有Windows的预编译包,解压即用,绿色健康。主流Linux通常集成swig的包,也可以下载源代码自己编译,SWIG非常小巧,通常安装不会出什么问题。用SWIG扩展Python,你需要有一个待扩展的C/C++库。这个库有可能是你自己写的,也有可能是某个项目提供的。这里举一个不浮夸的例子:希望在Python中用到SSE4指令集的CRC32指令。首先打开指令集的文档:https://software.intel.com/en-us/node/514245可以看到有6个函数。分析6个函数的原型,其参数和返回值都是简单的整数。于是书写SWIG的配置文件(为了简化起见,未包含2个64位函数):/* File: mymole.i */%mole mymole%{#include "nmmintrin.h"%}int _mm_popcnt_u32(unsigned int v);unsigned int _mm_crc32_u8 (unsigned int crc, unsigned char v);unsigned int _mm_crc32_u16(unsigned int crc, unsigned short v);unsigned int _mm_crc32_u32(unsigned int crc, unsigned int v);接下来使用SWIG将这个配置文件编译为所谓Python Mole Wrapperswig -python mymole.i得到一个 mymole_wrap.c和一个mymole.py。把它编译为Python扩展:Windows:cl /LD mymole_wrap.c /o _mymole.pyd -IC:\Python27\include C:\Python27\libs\python27.libLinux:gcc -fPIC -shared mymole_wrap.c -o _mymole.so -I/usr/include/python2.7/ -lpython2.7注意输出文件名前面要加一个下划线。现在可以立即在Python下使用这个mole了:>>> import mymole>>> mymole._mm_popcnt_u32(10)

㈣ 怎么用swig实现在python中继承C++接口类

你找个工具将这个接口API,自动转换成python版本的就可以了。好象是SWIG和Boost。 这两个以前看过,偶尔还试过几次。之所以建议你用自动工具,就是因为python对于C 扩展麻烦些,对于C语言接口可以使用ctypes和cython简单解决。不过C 如果用这些方法有时候被很麻烦。boost在linux里会经常用到,在windows下也可以使用。SWIG在一般的教程里都会提及到。SIP也是最近出名的。下面是一些参考资料,搜索来的。=== 使用工具进行扩展 ===虽然扩展过程并不复杂,但也可以使用许多已知的工具简化扩展过程。(1) SWIG由David Beazley创建,是一个自动的扩展构造工具。它读入注释的C/C 头文件,为python、tcl、perl等多种脚本语言产生wrap代码。SWIG可以包装大量C 特性到Python的扩展模块中。评价:swig简单,可以支持多种脚本文件,但支持的c 特性不完备。(2) SIP由Phil Thompson创建,是一个C 模块构造器,专门为C 的类创造wrapper。它曾经被用于创建PyQt和PyKDE扩展模块,因此比较出名。评价:支持C 特征很齐全,但比较复杂。(3) bgen该工具被包含在标准Python发布包中的模块构建工具集里,由Jack Jansen维护。它用于产生在Macintosh版本可用的Python扩展模块。(4) pyfort由Paul bois创建,用来产生Fortran语言生成的扩展模块。(5) cxx也由Paul Dubois创建,甫俯颠谎郯荷奠捅订拉是一个库,为Python的C 扩展提供了友好的API。Cxx允许将许多python对象(如list和tuple)使用到STL的运算中。库也提供了C 异常处理到python异常处理的转化。(6) WrapPy由Greg Couch创建,通过读入C 头文件来产生扩展模块。(7) Boost Python Library由David Abrahams创建。该库提供了更多与众不同的C wrap到python扩展中,而只需要对要扩展的C 类写很少的附加信息。评价:Boost为C 提供了许多实用的库,如Regex(正则表达式库)、Graph(图组件和算法)、concept check(检查泛型编程中的concept)、Thread(可移植的C 多线程库)、Python(把C 类和函数映射到Python之中)、Pool(内存池管理)等等。Boost总体来说是实用价值很高,质量很高的库。并且强调对跨平台的支持。但是Boost中也有很多是实验性质的东西,在实际的开发中实用需要谨慎。boost.python支持的c 特性较多,但是比较复杂。

㈤ android 怎么使用swig

一,下载SWIG,并设置好环境变量二以HelloJni为例子 导入ndk sample的HelloJni工程。 三 创建SWIG接口文件 在jni目录下新建文件Unix.i,输入SWIG代码:[cpp] view plain print?%mole Unix %{ #include <unistd.h> %} typedef unsigned int uid_t; extern uid_t getuid(void); 在src目录下创建代理类的包,名为:com.apress.swig四在命令行下调用SWIG在项目根目录下执行swig -java -package com.apress.swig -outdir src/com/apress/swig jni/Unix.i执行成功后会在src/com.apress.swig包下生成java jni代码,在jni目录下会有Unix_wrap.c文件。五将SWIG集成到Android构造过程中 在jni目录下创建my-swig-generate.mk文件:[cpp] view plain print?ifndef MY_SWIG_PACKAGE $(error MY_SWIG_PACKAGE is not defined.) endif MY_SWIG_OUTDIR:=$(NDK_PROJECT_PATH)/src/$(subst .,/,$(MY_SWIG_PACKAGE)) ifndef MY_SWIG_TYPE MY_SWIG_TYPE:=C endif #ifeq($(MY_SWIG_TYPE),cxx) # MY_SWIG_MODE:=c++ #else # MY_SWIG_MODE:= #endif LOCAL_SRC_FILES+=$(foreach MY_SWIG_INTERFACE,\ $(MY_SWIG_INTERFACES),\ $(basename $(MY_SWIG_INTERFACE))_wrap.$(MY_SWIG_TYPE)) #LOCAL_CPP_EXTENSION+=.cxx %_warp.$(MY_SWIG_TYPE) : %.i \ $(call host-mkdir,$(MY_SWIG_OUTDIR)) \ swig -java \ $(MY_SWIG_MODE) \ -package $(MY-SWIG_PACKAGE) \ -outdir $(MY_SWIG_OUTDIR) \ $< 修改jni目录下的Android.mk:[cpp] view plain print?LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := hello-jni LOCAL_SRC_FILES := hello-jni.c MY_SWIG_PACKAGE:=com.apress.swig MY_SWIG_INTERFACES:=Unix.i MY_SWIG_TYPE:=c include $(LOCAL_PATH)/my-swig-generate.mk include $(BUILD_SHARED_LIBRARY) 编译ndk.六 加入调用代码修改HelloJni.java:[java] view plain print?TextView tv = new TextView(this); tv.setText( stringFromJNI() +" uid:"+Unix.getuid()); setContentView(tv); 编译运行代码下载 http://download.csdn.net/detail/hai836045106/7937337

㈥ 如何编译c文件中调用 cython

以下总结出几种在Python 中调用 C/C++ 代码的方法——————————————————————–发现做便捷的是使用popenfrom os import popenpopen('/home/pengyan/Downloads/VIC/sanxia/vicNl -g /home/pengyan/Downloads/VIC/sanxia/xings_global')popen('/home/pengyan/Downloads/VIC/sanxia/rout /home/pengyan/Downloads/VIC/sanxia/xings_rout')?? 目前还不会用python 切换文件目录可以采用绝对路径,但是好像绝对路径时,计算速度变慢——————————————————————-使用ctypes 模块调用 C 动态库从Python2.5 开始, Python 开始提供 ctypes 模块来提供对 C 语言编译的动态库文件的调用。注意, 这里特指C 的动态库 ,用C++ 编译的动态库 ctypes 虽然能够加载,但调用时的函数名已经由于 C++ 的重载特性被加以修改,难以调用。 使用 ctypes 调用 C 动态库的好处在于不用进行额外的开发,可以直接使用编译好的动态库。 ctypes 提供了完整的 C 类型封装,也支持自定义类型,大大减少在调用过程中的工作量。 ctypes 的使用很简单,只需熟悉 python 封装与 C 中的对应关系即可。以下用一个简单的例子来说明:from ctypes import * #导入ctypes模块libc = cdll.LoadLibrary("libc.so.6") #加载libc动态库str = c_char_p(' Hello World! ') #使用char *在ctypes中的对应封装c_char_p,相当于char* str=”Hello World!”libc.printf(“yell: %s\n”, str ) #调用printf函数ctypes的功能当然远不止这些,有兴趣的同学可以参考这里 http://docs.python.org/library/ctypes.html使用Python 的扩展( Extending )机制ctypes很方便地可以调用 C 的动态库,但是对 C++ 编译的动态库,调用起来很困难。这种情况利用 Python 的 Extending 机制就可以解决。 Python 提供了一套完整的框架来使用 C/C++ 编写扩展库,可以很灵活的开发 C++ 扩展模块。这种方法的缺点是工作量比较大,需要为每一个方法编写接口,这里不做详细介绍,可以参考: http://docs.python.org/extending/extending.html#writing-extensions-in-c那么有什么办法可以高效的调用C++ 动态库呢,答案是 SWIG 。使用SWIG 生成扩展模块上面提到了Python 的扩展机制,缺点是工作量比较大,这里介绍一个工具 SWIG 。 SWIG 是一种简化脚本语言与 C/C++ 接口的开发工具,通过包装和编译 C 语言程序来达到与脚本语言通讯目的的工具。它正是基于 Python 的扩展机制,自动生成接口文件,再编译成可以被 Python 调用的动态库扩展模块。使用SWIG 生成扩展模块分为以下几步:将需要调用的代码编译成目标文件(.o) ;用SWIG 读取编写描述文件 (.i) ,生成接口文件 (.cxx) ;将接口文件编译为目标文件(.o) ;将接口文件的目标文件和原代码段的目标文件一起编译成动态库 ;假设有如下文件swig_ex.cpp 需要转换成扩展库的原始代码,包含一个int fact(int) 函数swig_ex.h 原始代码的头文件swig_ex.i SWIG描述文件swig_ex.i是一个描述文件,有 SWIG 自己的语法,比较简单,内容如下: %mole swig_ex%{ #define SWIG_FILE_WITH_INIT #include "swig_ex.h"%}int fact(int n); 再写一个Makefile 来把这些文件编译成动态库 : all: swig_ex.o swig_ex_wrap.o _swig_ex.soswig_ex.o: swig_ex.cpp swig_ex.h #编译源文件 g++ -fPIC -c swig_ex.cppswig_ex_wrap.o: swig_ex.i swig_ex.o #根据 SWIG 描述文件 (.i) 生成接口文件 (.cxx) ,再编译之 swig -c++ -python swig_ex.i g++ -O2 -fPIC -c swig_ex_wrap.cxx -I/home/work/linyi/autoframe/tool/python/include/python2.6/_swig_ex.so: swig_ex_wrap.o #将目标文件打包成动态库 g++ -shared swig_ex.o swig_ex_wrap.o -o _swig_ex.so.PHONY: cleanclean: rm -rf swig_ex_wrap.* swig_ex.py _swig_ex.so 编译好以后会有一个so 和 py 文件,写一个 setup.py 把他们安装到 python 目录就可以和其他模块一样被 python 调用了: Import swig_exswig_ex.fact(10) 参考文档地址:http://www.swig.org/Doc1.3/SWIGDocumentation.html原始但有效的方法除了上面这些方法,在Python 中借用 C/C++ 代码最原始有效的方法就是将代码编译成可执行程序,从 Python 里用 Popen 方法来调用获取输出。这种方法简单有效,缺点是不够灵活,有比较大的局限性,不过在很多情况下也已经足够了。 pipe = os.popen('./tool –a %s –b %s' % (“hello”, “world”))re = pipe.read() 其他方法以上这些方法基本上已经能满足Python 调用 C/C++ 的需求了,此外还有一些方法,例如使用 Boost.Python ,使用 Pyrex ,这些方法都能提供 Python 与 C/C++ 的交互。总结在Python 中引用 C/C++ 模块的方法较多,根据需要从中选择恰当的方法可以减少很多工作量。在Python 中引用 C/C++ 模块弥补了 Python 脚本测试框架的很多不足,在提高代码复用率的同时,模块的性能也大大提高。

㈦ 如何学习TensorFlow源码

如果从源码构建TensorFlow会需要执行如下命令:bazel build -c opt //tensorflow/tools/pip_package:build_pip_package对应的BUILD文件的rule为:sh_binary( name = "build_pip_package", srcs = ["build_pip_package.sh"], data = [ "MANIFEST.in", "README", "setup.py", "//tensorflow/core:framework_headers", ":other_headers", ":simple_console", "//tensorflow:tensorflow_py", "//tensorflow/examples/tutorials/mnist:package", "//tensorflow/models/embedding:package", "//tensorflow/models/image/cifar10:all_files", "//tensorflow/models/image/mnist:convolutional", "//tensorflow/models/rnn:package", "//tensorflow/models/rnn/ptb:package", "//tensorflow/models/rnn/translate:package", "//tensorflow/tensorboard", ],)sh_binary在这里的主要作用是生成data的这些依赖。一个一个来看,一开始的三个文件MANIFEST.in、README、setup.py是直接存在的,因此不会有什么操作。“//tensorflow/core:framework_headers”:其对应的rule为:filegroup( name = "framework_headers", srcs = [ "framework/allocator.h", …… "util/device_name_utils.h", ],)这里filegroup的作用是给这一堆头文件一个别名,方便其他rule引用。“:other_headers”:rule为:transitive_hdrs( name = "other_headers", deps = [ "//third_party/eigen3", "//tensorflow/core:protos_all_cc", ],)transitive_hdrs的定义在:load("//tensorflow:tensorflow.bzl", "transitive_hdrs")实现为:# Bazel rule for collecting the header files that a target depends on.def _transitive_hdrs_impl(ctx): outputs = set() for dep in ctx.attr.deps: outputs += dep.cc.transitive_headers return struct(files=outputs)_transitive_hdrs = rule(attrs={ "deps": attr.label_list(allow_files=True, providers=["cc"]),}, implementation=_transitive_hdrs_impl,)def transitive_hdrs(name, deps=[], **kwargs): _transitive_hdrs(name=name + "_gather", deps=deps) native.filegroup(name=name, srcs=[":" + name + "_gather"])其作用依旧是收集依赖需要的头文件。“:simple_console”:其rule为:py_binary( name = "simple_console", srcs = ["simple_console.py"], srcs_version = "PY2AND3", deps = ["//tensorflow:tensorflow_py"],)py_library( name = "tensorflow_py", srcs = ["__init__.py"], srcs_version = "PY2AND3", visibility = ["//visibility:public"], deps = ["//tensorflow/python"],)simple_console.py的代码的主要部分是:from __future__ import absolute_importfrom __future__ import divisionfrom __future__ import print_functionimport codeimport sysdef main(_): """Run an interactive console.""" code.interact() return 0if __name__ == '__main__': sys.exit(main(sys.argv))可以看到起通过deps = [“//tensorflow/python”]构建了依赖包,然后生成了对应的执行文件。看下依赖的rule规则。//tensorflow/python对应的rule为:py_library( name = "python", srcs = [ "__init__.py", ], srcs_version = "PY2AND3", visibility = ["//tensorflow:__pkg__"], deps = [ ":client", ":client_testlib", ":framework", ":framework_test_lib", ":kernel_tests/gradient_checker", ":platform", ":platform_test", ":summary", ":training", "//tensorflow/contrib:contrib_py", ],)这里如果仔细看的话会发现其主要是生成一堆python的模块。从这里貌似可以看出每个python的mole都对应了一个rule,且mole依赖的mole都写在了deps里。特别的,作为一个C++的切入,我们关注下training这个依赖:py_library( name = "training", srcs = glob( ["training/**/*.py"], exclude = ["**/*test*"], ), srcs_version = "PY2AND3", deps = [ ":client", ":framework", ":lib", ":ops", ":protos_all_py", ":pywrap_tensorflow", ":training_ops", ],)这里其依赖的pywrap_tensorflow的rule为:tf_py_wrap_cc( name = "pywrap_tensorflow", srcs = ["tensorflow.i"], swig_includes = [ "client/device_lib.i", "client/events_writer.i", "client/server_lib.i", "client/tf_session.i", "framework/python_op_gen.i", "lib/core/py_func.i", "lib/core/status.i", "lib/core/status_helper.i", "lib/core/strings.i", "lib/io/py_record_reader.i", "lib/io/py_record_writer.i", "platform/base.i", "platform/numpy.i", "util/port.i", "util/py_checkpoint_reader.i", ], deps = [ ":py_func_lib", ":py_record_reader_lib", ":py_record_writer_lib", ":python_op_gen", ":tf_session_helper", "//tensorflow/core/distributed_runtime:server_lib", "//tensorflow/core/distributed_runtime/rpc:grpc_server_lib", "//tensorflow/core/distributed_runtime/rpc:grpc_session", "//util/python:python_headers", ],)tf_py_wrap_cc为其自己实现的一个rule,这里的.i就是SWIG的interface文件。来看下其实现:def tf_py_wrap_cc(name, srcs, swig_includes=[], deps=[], copts=[], **kwargs): mole_name = name.split("/")[-1] # Convert a rule name such as foo/bar/baz to foo/bar/_baz.so # and use that as the name for the rule procing the .so file. cc_library_name = "/".join(name.split("/")[:-1] + ["_" + mole_name + ".so"]) extra_deps = [] _py_wrap_cc(name=name + "_py_wrap", srcs=srcs, swig_includes=swig_includes, deps=deps + extra_deps, mole_name=mole_name, py_mole_name=name) native.cc_binary( name=cc_library_name, srcs=[mole_name + ".cc"], copts=(copts + ["-Wno-self-assign", "-Wno-write-strings"] + tf_extension_copts()), linkopts=tf_extension_linkopts(), linkstatic=1, linkshared=1, deps=deps + extra_deps) native.py_library(name=name, srcs=[":" + name + ".py"], srcs_version="PY2AND3", data=[":" + cc_library_name])按照SWIG的正常流程,先要通过swig命令生成我们的wrap的c文件,然后和依赖生成我们的so文件,最后生成一个同名的python文件用于import。这里native.cc_binary和native.py_library做了我们后面的两件事情,而swig命令的执行则交给了_py_wrap_cc。其实现为:_py_wrap_cc = rule(attrs={ "srcs": attr.label_list(mandatory=True, allow_files=True,), "swig_includes": attr.label_list(cfg=DATA_CFG, allow_files=True,), "deps": attr.label_list(allow_files=True, providers=["cc"],), "swig_deps": attr.label(default=Label( "//tensorflow:swig")), # swig_templates "mole_name": attr.string(mandatory=True), "py_mole_name": attr.string(mandatory=True), "swig_binary": attr.label(default=Label("//tensorflow:swig"), cfg=HOST_CFG, executable=True, allow_files=True,),}, outputs={ "cc_out": "%{mole_name}.cc", "py_out": "%{py_mole_name}.py", }, implementation=_py_wrap_cc_impl,)_py_wrap_cc_impl的实现为:# Bazel rules for building swig files.def _py_wrap_cc_impl(ctx): srcs = ctx.files.srcs if len(srcs) != 1: fail("Exactly one SWIG source file label must be specified.", "srcs") mole_name = ctx.attr.mole_name cc_out = ctx.outputs.cc_out py_out = ctx.outputs.py_out src = ctx.files.srcs[0] args = ["-c++", "-python"] args += ["-mole", mole_name] args += ["-l" + f.path for f in ctx.files.swig_includes] cc_include_dirs = set() cc_includes = set() for dep in ctx.attr.deps: cc_include_dirs += [h.dirname for h in dep.cc.transitive_headers] cc_includes += dep.cc.transitive_headers args += ["-I" + x for x in cc_include_dirs] args += ["-I" + ctx.label.workspace_root] args += ["-o", cc_out.path] args += ["-outdir", py_out.dirname] args += [src.path] outputs = [cc_out, py_out] ctx.action(executable=ctx.executable.swig_binary, arguments=args, mnemonic="PythonSwig", inputs=sorted(set([src]) + cc_includes + ctx.files.swig_includes + ctx.attr.swig_deps.files), outputs=outputs, progress_message="SWIGing {input}".format(input=src.path)) return struct(files=set(outputs))这里的ctx.executable.swig_binary是一个shell脚本,内容为:# If possible, read swig path out of "swig_path" generated by configureSWIG=swigSWIG_PATH=tensorflow/tools/swig/swig_pathif [ -e $SWIG_PATH ]; then SWIG=`cat $SWIG_PATH`fi# If this line fails, rerun configure to set the path to swig correctly"$SWIG" "[email protected]"可以看到起就是调用了swig命令。“//tensorflow:tensorflow_py”:其rule为:py_library( name = "tensorflow_py", srcs = ["__init__.py"], srcs_version = "PY2AND3", visibility = ["//visibility:public"], deps = ["//tensorflow/python"],)

㈧ 如何用Python封装C语言的字符串处理函数

在C语言中,字符串处理是每天都要面对的问题。我们都知道C语言中其实并没有一种原生的字符串类型,‘字符串’在C语言里只是一种特殊的以''结尾的字符数组。因此,如何将C语言与更高层次的Python语言在‘字符串’处理这个问题上对接是一个有难度的问题。所幸有swig这种强大的工具。如何封装一个函数,它修改参数字符串的内容假如有这样一个C语言的函数,<!– lang: cpp –>void FillZero(char* pc,size_t * piLen){size_t i=0;while(i++<*piLen/2 )*pc++ = '0';*pc = 0;*piLen = i+1;}这个函数的功能是把字符串变成n个0。不过我们更关注函数的形式。这样的函数,表面上看char* pc是函数的参数,可是实际上它才是函数的返回值和执行的结果。piLen这个参数既是pc的最大长度,也是新的字符串的长度。我们直接用python封装,看看运行结果。Type "help", "right", "credits" or "license" for more information.>>> import cchar>>> s='123456'>>> cchar.FillZero(s,6)Traceback (most recent call last):File "<stdin>", line 1, in <mole>TypeError: in method 'FillZero', argument 2 of type 'size_t *'结果差强人意,不是我们想要得到的结果。函数的第二个参数为size_t* 我们很难用python来表示,而且python中也不存在既是输入,也是输出的参数。swig有一个标准库,其中有一个cstring.i文件就是用来解决C语言字符串类型的问题。我们在.i文件中加入这样几行<!– lang: cpp –>%include "cstring.i"%cstring_output_withsize(char* pc,size_t* pi)void FillZero(char* pc, size_t* pi);然后运行看结果Type "help", "right", "credits" or "license" for more information.>>> import cchar>>> cchar.FillZero(10)'00000\x00'>>> s=cchar.FillZero(10)>>> print s00000我们看函数的变化。首先在python里, FillZero变成了只有一个参数的函数。然后函数的返回值变成了一个字符串。其实cstring_output_size其实是一个宏,通过这个宏的定义改变了函数的形式,直接在Python中得到我们想要的结果。其实类似cstring_output_size的宏还有好几个,我列举一下:cstring_output_allocate(char *s,free($1));第一个参数是指向字符串地址的指针,第二个参数为释放空间的方法。大家考虑这一下这样的函数:void foo(char* & s){s = (char*)malloc(10);memcpy(s,"123456789",9);}s这个参数表面上看是输入,实际上是函数真正的输出。 函数中真正改变的东西是char&s指向的字符串的值。而且char&这个类型, python或者其他脚本语言里应该都没有对应的类型。那么我们用cstring_output_allocate将这个函数转换成另外一个形式的python或者其他脚本语言的函数。转换后的函数其实是这样的,以python为例str foo()。<!– lang: cpp –>%mole a%include "cstring.i"%{void foo(char*& s);%}%cstring_output_allocate(char *&s, free(*$1));void foo(char *&s);在python中的调用:<!– lang: python –>>>> import a>>> a.foo()'123456789'>>>cstring_output_maxsize(char *path, int maxpath);第一个参数也是可以改变的字符串首地址,第二个参数为字符串的最大长度。在Python中调用的时候,只有maxpath这个参数,返回字符串。cstring_output_allocate(char *s, free($1));第一个参数为指向字符串首地址的指针,第二个参数为释放指针的方法。这个宏主要是封装一种直接在函数内部malloc空间的函数。在Python中调用时没有参数,直接返回字符串。cstring_output_allocate_size(char *s, int slen, free(*$1));这个相当于前面两个函数的组合。在函数内部malloc空间,然后将字符串长度通过slen返回。其实在调用的时候非常简单,没有参数,直接返回字符串。如何处理c++的std::stringstd::string是C++标准类库STL中常见的类。在平时工作中大家肯定是没少用。在python中如何封装std::string? swig提供了标准库例如函数:<!– lang: cpp –>string Repeat(const string& s){return s+s;}只要在swig中加入这样几行:<!– lang: cpp –>%include "std_string.i"using namespace std;string Repeat(const string& s);运行结果:Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)[GCC 4.4.5] on linux2Type "help", "right", "credits" or "license" for more information.>>> import cchar>>> cchar.Repeat('123')'123123'使用起来很方便,但需要注意的是,假如函数的参数的内容是可以被修改,就不能用这种方式封装。例如:<!– lang: cpp –>void repeat(string s){s+=s;}这样的函数直接使用 'std_string.i' 就是无效的。遇到这种函数,只能用C语言封装成 void repeat(chars, int maxsize), 再用swig调用 'cstring_output_withsize' 这个宏再封装一次了。

㈨ swig 生成的python接口,在python中怎么传入void*入参

如果一个函数的参数是一个指针,Python如何传递?下面的方法是可以直接传递列表。把这个加到.i文件中。%{static intconvert_darray(PyObject *input, int *ptr, int size) { int i; if (!PySequence_Check(input)) { PyErr_SetString(PyExc_TypeError,"Expecting a sequence"); return 0; } if (PyObject_Length(input) != size) { PyErr_SetString(PyExc_ValueError,"Sequencesize mismatch"); return 0; } for (i =0; i < size; i++) { PyObject *o =PySequence_GetItem(input,i); if (!PyFloat_Check(o)) { Py_XDECREF(o); PyErr_SetString(PyExc_ValueError,"Expecting a sequence offloats"); return 0; } ptr[i] = PyFloat_AsDouble(o); Py_DECREF(o); } return 1;}%}%typemap(in) int[ANY](int temp[$1_dim0]) { if (!convert_darray($input,temp,$1_dim0)) { return NULL; } $1 = &temp[0];}