用swig封装法做测试

如何用SWIG封装c++接口给java使用? SWIG(Simplified Wrapper and Interface Generator)是一个将C/C++接口转换为其他语言接口的工具,从而可以讲C/C++的库集成到其他语言的系统中。目前SWIG已经可以支持Python, Java, C#,Ruby,PHP,R语言等十多种语言。3.用gcc/g++编译生成的接口代码, 以及对应语言的代码。1.编写swig的interface文件,指明接口的内容。这个Demo将cpp的代码接口转化为JAVA的代码接口。demoJNI.java , JNI的接口。 阅读详情

在嵌入式软件产品开发过程中,通常会预留测试接口以便测试。由于产品所使用的语言可能是编译型的静态语言,如果测试程序也用一样的语言编写,虽然数据结构的一致性上没有问题,但是测试程序的灵活性上则受限于产品所用语言。

举例说明,在产品中有一个测试程序,使用了VC,有一些基础模块用于构造对应于消息的结构体,有跟主控通讯的模块,以及一个简单的逻辑判断模块做字段的比较,在产品开发前期该工具起到了很大作用,但是到后期则由于灵活性问题而使用较少,测试部较多的利用robot类的工具从界面上做测试。分析原因可以看出,由于缺乏通用语言的一些特性,导致该工具使用起来有一些缺陷,完成的任务也相对较简单。如果利用该工具的思路,但是添加上语言特性,则是本文的重点。

本文介绍一种通过swig做接口,利用脚本语言的动态性以及其他便利的语言特性简化测试程序的编写,可以克服上面提到的问题。

 


如果还是用c语言编程,要引入逻辑判断和分支比较的功能非常麻烦,等于是自己做一个脚本语言,难度非常大,并且会非常耗费时间。如何利用已有脚本语言的灵活性,并且能与目标语言c自动结合起来,把c语言中的函数和数据结构等封装为脚本语言的扩展,就可以达到我们的目的了。

 

下面就主要描述把c语言中的函数和数据结构描述为脚本扩展语言的流程:

1)             写一个接口文件

接口文件ter.i,是一个swig处理的输入文件其中包括了c中的数据结构声明和函数声明,以及用typemaps技术对c语言和脚本语言之间转换的一些控制。由于其中牵涉到一些细节,所以会详细讲解:

%module ter

%{

#include <stdio.h>

#include <stdlib.h>

#include "msg.h"

#include "udp.h"

%}

 

上面是按部就班的,包括模块名,以及需要引用的头文件,msg.h中包含了所有需要的数据结构。而udp.h则是对udp socket的简单封装,本来ruby中也有udp模块,不过发现按照例子代码,总是无法收发udp包,所以自己封装了一下(补充注释:其实ruby的udp模块很好用的,不需要封装,但是 Socket.do_not_reverse_lookup=true 这句话是不能少的,否则你就等着接收超时吧)。

 

由于很多数据结构中有unsigned char name[32]类似的数组,其内容可能是字符串,也可能是数组,由于这种字段默认的被swig封装为用户字段,从ruby脚本中读写比较麻烦,所以采用下面的代码,当写字段的时候,用ruby的string对其赋值,当读的时候,会封装为字符串输出(ruby的字符串可以包含/0字符,不过程序中添加了一个判断,如果在非结尾处遇到0,后面也全部是0,就把0前面的作为字符串输出,否则把整个数组内容作为ruby字符串)。

%typemap(memberin,noblock=1) unsigned char [ANY]{

 

}

%fragment("SetArr","header") {

       void SetArr(VALUE str,unsigned char buf[],int len)

       {

              int minlen=min(len,RSTRING_LEN(str));

              memset(buf,0,len);

              memcpy(buf,RSTRING_PTR(str),minlen);        

       }    

}

%typemap(in,noblock=1,fragment="SetArr") unsigned char [ANY] {

       SetArr($input,arg1->$1_name,$1_dim0);    

}

 

%fragment("GetArr","header") {

       VALUE GetArr(unsigned char buf[],int len)

       {

              int i=0,next=0;

              int isStrZ=0;

              VALUE str;

              for(i=0;i<len;i++)

              {    

                     if(buf[i]==0)

                     {

                            isStrZ=1;

                            break;

                     }

              }

              for(next=i+1;next<len;next++)

              {

                     if(buf[next]!=0)

                     {

                            isStrZ=0;

                     }

              }

              if(isStrZ==0)

              {

                     str=rb_str_new(buf,len);

              }

              else

              {

                     str=rb_str_new2(buf);

              }    

              return str;

       }    

}

 

%typemap(out,noblock=1,fragment="GetArr") unsigned char [ANY]{

       $result=GetArr($1,$1_dim0);

}

 

%include "msg.h"

注意上面的fragment主要是为了节省代码空间,否则会到处都是一样的代码。而%typemap(memberin,noblock=1) unsigned char [ANY]这句则是取消swig预订的操作,使用我们的SetArr操作。

 

下面的代码就比较平凡了,主要是针对每个数据结构,添加一些方便的操作。

 

%define MAKE_STRUCT(T)

%extend T {

    T() {

        T *pT;

        pT=(T *)malloc(sizeof(T));

        memset((void *)pT,0,sizeof(*pT));

        return pT;

    }

    ~T(){

        free($self);

    }

 

    int length(){

        return sizeof(*$self);

    }

   

    T* shape(VALUE str){

           char *buf=RSTRING_PTR(str);

           int len=RSTRING_LEN(str);

           int slen=sizeof(*$self);

           if(len!=slen)

           {

                  rb_raise(rb_eTypeError,"the struct %s has %d size, but %d size supplyed,not equal/n",#T,slen,len);

           }

           memcpy($self,buf,len);

           return $self;

    }

 

    VALUE to_a(){

        int i=0;

        int len=sizeof(*$self);

        char *ptr=(char *)$self;

        VALUE arr = rb_ary_new2(len);

        for(i=0;i<len;i++)

        {

            rb_ary_push(arr, INT2NUM(ptr[i]));

        }

        return arr;

    }

    VALUE to_binstr(){

           char *buf=(char *)$self;

           int len=sizeof(*$self);

           return rb_str_new(buf,len);

    }

   

    VALUE to_s(){

        VALUE s;

        int i=0;

        unsigned char buf[1024]={0};

        int len=sizeof(T);

        int sLen=0,sIdx=0;

        unsigned char *ptr=(unsigned char *)$self;

        for(i=0;i<len;i++)

        {

            sLen=sprintf(buf+sIdx,"//0x%02X",ptr[i]);

            sIdx+=sLen;

            if(sIdx>=1023)

            break;

        }

        buf[sIdx>1023?1023:sIdx]=0;

        s=rb_str_new2(buf);

        return s;

    }

};

%enddef

 

其中比较关键的shape就是将一个string对象转换成用户定义的数据结构对象,方便后面操作。在接口文件中添加MAKE_STRUCT(T_GeneralConfig) 就会把上面的函数功能添加到T_ GeneralConfig结构中。

 

Udp 的c代码如下:

int Sock_Open(T_Sock *sock,char *ip,unsigned short port,char *localip,unsigned short localport,int timeout);

int Sock_Send(T_Sock *sock,char *buf,int len);

int Sock_Recv(T_Sock *sock,char *buf,int len,  struct sockaddr* from,int* fromlen);

int Sock_Close(T_Sock *sock);

 

这些代码如果不封装,使用起来非常麻烦,所以封装如下:

%extend T_Sock {

       ...

      

       VALUE Recv()

       {

              char buf[2048]={0};

              int len=sizeof(buf);

              int ret=0;

              struct sockaddr from={0};

              struct sockaddr_in *pAddr=NULL;

              int fromlen=sizeof(from);

             

              VALUE data;

              VALUE host;

              VALUE port;

              VALUE arr;

              VALUE subarr;

             

              T_Sock *tSock=(T_Sock *)$self;

 

              ret=Sock_Recv(tSock,buf,len,&from,&fromlen);

              if(ret>0)

              {

                     data=rb_str_new(buf,ret);

                    

                     pAddr=(struct sockaddr_in *)&from;

                     host=rb_str_new2(inet_ntoa(pAddr->sin_addr));

                     port=INT2NUM(ntohs(pAddr->sin_port));

                     subarr=rb_ary_new2(2);

                     rb_ary_push(subarr,host);

                     rb_ary_push(subarr,port);                  

                    

                     arr=rb_ary_new2(3);

                     rb_ary_push(arr,data);

                     rb_ary_push(arr,INT2NUM(SOCK_OK));

                     rb_ary_push(arr,subarr);

                     return  arr;   

              }

              else if(ret==0)

              {

                     arr=rb_ary_new2(2);

                     rb_ary_push(arr,Qnil);

                     rb_ary_push(arr,INT2NUM(SOCK_EXIT));

                     return arr;

              }

              else if(ret<0)

              {

                     int error=GetLastError();

                     if(tSock->timeout>0 && error==WSAETIMEDOUT)

                     {

                            arr=rb_ary_new2(2);

                            rb_ary_push(arr,Qnil);

                            rb_ary_push(arr,INT2NUM(SOCK_TIMEOUT));

                            return arr;             

                     }

                     else

                     {

                            arr=rb_ary_new2(3);

                            rb_ary_push(arr,Qnil);

                            rb_ary_push(arr,INT2NUM(SOCK_ERROR));

                            rb_ary_push(arr,INT2NUM(error));

                            return arr;      

                     }

              }

              return Qnil;

       }

       ...

 

}

其中其他的函数已经省略,recv之后,会根据情况返回不同的值,正常读取后,会返回接收到的数据,状态码,以及对端地址,如果对端优雅关闭,则返回Qnil和对端socket退出,如果超时返回Qnil,和超时状态,否则返回Qnil和错误号。其中超时采用了setsockopt来设置接收超时,在socket创建的时候就设置好了,无法中途修改。

2)             写脚本文件

写好接口文件后,写一个extconf.rb,然后用ruby处理后生成一个makefile文件,用nmake调用后就会生成.so的dll文件。只要用require 'ter'      就可以使用封装的功能了。下面按照代码实例说明:

 

代码中封装了一个TerSock来处理socket以及与终端测试接口的连接。

TerSock初始化的时候打开socket

              @sock=Ter::T_Sock.new

              @sock.Open(serverip,port,"0",localport,timeout)

用户想要跟终端连接的时候调用:

              msg=["user","pass",@localport].pack("a8a8S")

              send(TEST_CONNECT,msg)

              send(TEST_BEGIN)

    其中send是

              conn=[2,0,code,msg.length].pack("VVVS")

              if msg!=""

                     conn<<msg

              end

              ret=@sock.Send(conn);

              return ret

              前面的pack用来完成T_Message头部的封装,msg部分则是用户提供的,合起来后调用udp socket的send发送到终端

 

Recv则是:

              while true

                     data=@sock.Recv()

                     if data[1]==Ter::SOCK_OK

                            _,_,respcode,len=data[0].unpack("VVVS");

                            data[0]=data[0][14..14+len-1]

                            return data if respcode==code

                     elsif data[1]==Ter::SOCK_TIMEOUT

                            puts "socket timeout";

                            break

                     elsif data[1]==Ter::SOCK_EXIT

                            puts "socket exit"

                            break

                     elsif data[1]==Ter::SOCK_ERROR

                            puts "error #{data[2]}"

                            break

                     end

              end

       接收之后判断状态,如果是有效数据并且是我们期望的消息号,把数据头剥离后剩下的数据发送给用户。

对于所有的数据结构,一开始都创建了一个对象,

$struct=%w{ T_GeneralConfig  T_CallTerMsg T_MccConfState}

$h={}

$struct.each {|name| eval(" $h[/"#{name}/"]=Ter::#{name}.new") }

def get_struct(name)

       return $h[name]

end

这样用户就可以用get_struct得到相应的对象了。

 

    下面以获取和设置一般设置的终端名为例:

           name="xxx"

           code=0x10090 #general query

           msg=[0x10010].pack("L")

           @ter.send(code,msg)

           data=@ter.recv(0x11010)

   

    这段代码构造了通用查询,查询一般配置

 

           if data[1]==Ter::SOCK_OK

                  ret=check("T_GeneralConfig",data[0]) 

           elsif data[1]==Ter::SOCK_TIMEOUT

                  puts "socket timeout";

           elsif data[1]==Ter::SOCK_EXIT

                  puts "socket exit"

           elsif data[1]==Ter::SOCK_ERROR

                  puts "error #{data[2]}"

           end

    这里判断返回的代码,其中check函数是关键,

           def check(msg,data)

                  $h[msg].shape(data)

                  if block_given?

                         return false if not yield $h[msg]

                  end

                  return true

end

 

如果没有给定块,则只是把收到的数据导入到全局的hash表中的数据结构中,否则会把判断权交给后面的块,并且把执行结果返回,用这个执行结果,我们就可以判断数据结构的值是否符合我们在块中设置的条件了。

 

           t=get_struct("T_GeneralConfig")

           t.acTerminalName=name

           str=t.to_binstr()

           @ter.send(0x10010,str)

 

这里是设置终端名并发送到终端

 

           code=0x10090 #general query

           msg=[0x10010].pack("L")

           @ter.send(code,msg)

           sleep(1)

           data=@ter.recv(0x11010)

这里再取到终端一般设置数据结构。

          

           if data[1]==Ter::SOCK_OK

                  ret=check("T_GeneralConfig",data[0]) { |t| t.acTerminalName==name }

                  assert(ret)             

           elsif data[1]==Ter::SOCK_TIMEOUT

                  puts "socket timeout";

           elsif data[1]==Ter::SOCK_EXIT

                  puts "socket exit"

           elsif data[1]==Ter::SOCK_ERROR

                  puts "error #{data[2]}"

           end 

在check函数后面附加了块对一般设置的名字字段做了判断,如果名字和我们设置的名字不一样,就会被testunit的assert记录。在执行多次测试后,看一下testunit的结果,就知道测试的情况了。
用swig 封装C++ 动态库的实践 python 调用C++ 有很多方案。 swig 还是比较好用的。 需求: 假设有一个现成的C++ 库 a.so 和 头文件 a.h如何通过python 来调用 a.so 里面的功能接口。 最开始我误认为必须有 a.so 的源代码cpp和a.h 才行。实践过发现,不需要源代码,swig可以根据头文件就自动生成一个可以供python调用的桥接so库的代码,在编译这个代码的时候,只要把a.so链... 阅读详情

相关推荐

使用SWIG封装恒生极速UFT接口(Python3)

使用SWIG封装恒生极速UFT接口(Python3) 一、准备工作 参考资料 CTP Python API及Demo(利用Swig 封装)Windows版(traderapi),20191208,作者:景色正好。 Swig转换C++接口中文乱码解决方案,作者:景色正好 SWIG 简介PDF 官方教程 SWIG and Python    Demo只能登录一个账户、只有主线程运行,了解Python多线程可同步多项任务。 多任务也能使用异步实现。 景色大佬在优快云

GXY493的博客 1149

如何在 SWIG 中处理 void* 参数

在使用 SWIG 将 C++ 代码绑定到 Python 时,遇到一个问题:如何处理 void* 参数。void* 是一个通用的指针类型,可以指向任意类型的数据。在 C++ 中,void* 参数通常用于传递各种类型的对象,而这些对象在 Python 中往往是不同的类型。因此,在 SWIG 中需要一种方法来将 void* 参数映射到相应的 Python 类型。

D0126_的博客 659

SWIG打包C++为python接口

SWIG C++ ->python打包方法 1. swig安装 1.1. windows 环境下安装swig Link: http://www.swig.org/download.html 直接下载swigwin 将下载后的swigwin.zip解压到本地任意目录 将解压后的目录打包,将swig.exe配置到PATH环境变量中 在cmd中测试输入swig,出现‘Must ...

阿呆的隐秘角落 845

SWIG 学习笔记(一)

关于char* 全局 char* 变量 SWIG 使用malloc() 或者 new 来给新值分配内存。比如如下形式的一个变量: char  *foo ; SWIG 生成如下代码: /* C mode */ void foo_set(char *value) { if (foo) free(foo); foo = (char *) malloc(strlen(valu

royer的专栏 1451

SWIG 和 JNA / JNI 等 C 接口封装工具及进行 C 接口的封装

SWIG 是一个软件开发工具,是一个 封装 C/C++ 动态库供其他编程语言调用的神器。使用它可以简化不同语言与与 C/C++ 语言的交互。简单点说,SWIG 是一个编译器,它以 C/C++的声明为输入,创建从其他语言包括常见的脚本语言如 Javascript、Perl、PHP、Python、Tcl 和 Ruby。支持的语言列表还包括非脚本语言,如 C#,D,Go language,Java,包括 Android,Lua,OCaml,Octave,Scilab 和 R。还支持几种解释和编译的 Scheme

jiegiser博客 481

【ESP32】1.编译、烧录、创建工程

本文介绍了在VSCode中搭建ESP32开发环境并烧录"Hello World"工程的过程。首先通过串口工具成功下载固件后,解决了OpenOCD报错问题。针对头文件无法识别的问题,修改了c_cpp_properties.json配置文件,调整了编译器路径和IntelliSense模式。文章还详细说明了创建新工程的步骤,包括选择芯片型号和项目模板,并验证了串口打印功能。最后提醒在项目构建时要等待完成,避免文件缺失。整个流程涵盖了环境搭建、代码烧录、调试及新项目创建等关键环节。

梁山1号 1483

SWIG小例子

这个Android平台式建立在Linux OS平台上的,是一个多用户平台。 它运行的应用程序在一个虚拟机sandbox和把他们当做不同的用户 来让平台安全。在Linux上,每一个用户都分配一个用户ID,和用户ID 能够被PoSIX os API的getuid函数访问。作为一个独立的平台编程语言, Java并不能提供获得这些函数。作为这个例子程序的一部分,     1.写一个Swig接口文

CodeMyDream的专栏 779

合规批量下载美国上市公司年报数据的一些经验和总结

本文总结了使用Python脚本批量下载和处理美国上市公司SEC报告的技术经验。通过CIK代码查询SEC EDGAR系统,生成特定日期和报告类型的URL,并使用Selenium和Requests库下载报告内容。流程包括数据获取、文件下载、Excel处理和多线程优化,确保高效处理几百条数据。关键技术挑战包括SEC访问限制、动态网页内容和数据完整性,解决方案包括设置合规的User-Agent、使用Selenium模拟浏览器行为以及错误日志记录。最佳实践包括模块化设计、多线程优化和严格遵守SEC合规性。该自动化流程

jyfool的博客 1634

swig-c/c++与高级脚本语言之间的胶水工具

SWIG是c/c++与高级脚本语言之间的胶水工具。http://www.swig.org/一个简单的例子http://www.swig.org/tutorial.htmlc语言代码 /* File : example.c */ #include &lt;time.h&gt; double My_variable = 3.0; int fact(int n) { if (n ...

huang_yx005的博客 492

Qt6.5.1+WebRTC学习笔记(十二)环境搭建流媒体服务器(ubuntu22.04+SRS)

若只是实现一对一通信,仅使用webrtc就足够了。但有时间需要进行多个人的直播会议,当人比较多时,建议使用一个流媒体服务器,笔者使用的是SRS。这个开源项目资料比较全,笔者仅在此记录下搭建过程。

aggs1990的专栏 3362

洛奇 服务器文件,MabinogiG20S2 [洛奇G20服务端]

Code:Titles:>set_title /id: /add /remove Parameters for titles>set_title /id:60001 /add add devcat title>set_title /id:60001 /remove remove devcat title===========================...

weixin_30813385的博客 4301

SWIG 使用经验

SWIG 使用经验 Posted on 2012 年 9 月 11 日 by tristan 啦啦啦,先定个基调:2   青年欢乐多~ 1.入正题,先讲一下为何要采用SWIG或者类似的工具来连接C++和python C++的神奇之处就不用在此赘述了,只谈天使的另一面——魔鬼面孔。C++语法严谨,一不小心容易造成整个软件崩溃甚至系统崩溃(你可以姑且认为是“指针”这个小情人惹的祸),内存

lionzl的专栏 1771

深入剖析一个卷积块(ConvBlock)

深入剖析一个卷积块(ConvBlock)

qq_45670407的博客 1920

Swig与Perl,使用Swig给Perl封装C++扩展库

SWIG(Simplified Wrapper and Interface Generator)是一个用于构建 C 和 C++ 程序脚本语言接口的软件开发工具。使用SWIG可以简便的给Perl,Python,Tcl等语言封装基于C/C++实现的扩展库。下面是一个简单的例子,该扩展使用的源文件有:C++源程序(包含一个头文件),SWIG的配置文件,perl的测试文件。

weixin_56793272的博客 954

maya权重拷贝一对一,一对多

是不是有时候盔甲很多很碎头很大,用代理一个个拷贝很麻烦吧 用下面代码直接运行进行一对多或者一对一拷贝 第一个先选择参考物体,加选其他一堆有的没的有权重或没权重的物体执行一键拷贝,就可以啦 以下是源码送上,带走吧 ------------------------ #! -*- coding:utf -8 -*- #author:liubingdong #date:20...

weixin_30852367的博客 1531

51-14 Retentive Network,RetNet 多尺度保留机制序列建模论文精读

RetNet 提出了多尺度保留机制序列建模,该机制支持三种计算范式,即并行、循环和分块循环。RetNet有更好的全局注意力建模、高效的计算效率、对遮挡的鲁棒性、支持基于注意力的图像生成、与置信度相关的门控机制和多任务学习等特点,对不同视觉任务可以共享历史注意力记忆,可以同时进行分类、分割、检测等任务。RetNet在视觉领域应该有广阔的应用前景。

AIgraphX 1613

SWIG 封装C++接口给Python调用

文章目录什么是SWIG下载添加系统环境变量使用C++封装编写封装说明文件调用swig封装使用VS编译1. 新建动态链接库项目2. 配置输出类型3. 添加Python 库编译输出调用测试参考 什么是SWIG SWIG is a software development tool that connects programs written in C and C++ with a variety o...

Reach Higher 1429

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

分别在win10和Linux上用SWIG将c++封装成python动态库

  将C++封装成python库的目的是,在兼顾python的开发效率的同时,有提高的python运行效率。 在WIN10上 1.安装 SWIGWIN:https://sourceforge.net/projects/swig/,下载之后解压,并添加环境变量。 2.建立要封装的源文件和头文件 /*hello.cpp*/ #include"stdio.h" int hello_print...

柳常青的博客 1217

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

SWIG介绍和使用

SWIG 是一种软件开发工具,可将用 C 和 C++ 编写的程序与各种高级编程语言连接起来。SWIG 与不同类型的目标语言一起使用,包括常见的脚本语言,如 Javascript、Perl、PHP、Python、Tcl 和 Ruby。支持的语言列表还包括非脚本语言,例如 C#、D、Go 语言、Java,包括 Android、Lua、OCaml、Octave、Scilab 和 R。

赶路人儿 3922

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

windows下 用SWIG工具给python封装c/c++库

SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。 SWIG能应用于各种不同类型的语言,包括常用脚本编译语言,例如Perl, PHP, Python, Tcl, Ruby 和 PHP。 SWIG普遍应用于创建高级语言解析或汇编程序环境、用户接口、作为一种用来测试C/C++或进行原型设计的工具。 工作中碰到了一个小问题:有一个加密/解密的程序原本是用C++语言写的,后来需要用Python来实现调用。简单粗暴的办法是照着C++代码重写一个Python版本的程序,但.

qq_34440409的博客 1267

c#利用SWIG调用c++dll学习总结

开发环境:操作系统:windows 7 IDE:Microsoft Visual Studio Professional 2015 SWIG: 3.0.12swig的介绍详细介绍可看官网,一下贴出官网上的原话: SWIG is a software development tool that connects programs written in C and C++ with a vari

liu14lang的博客 7392

Windows上Python使用swig调用C++

安装swig和VS swig是一种可以将C++代码转换为多种脚本语言封装的工具,可以在http://www.swig.org/下载(Windows users should download swigwin-3.0.12 which includes a prebuilt executable. ),解压后将swig.exe的路径添加到环境变量path中即可使用swig。 我是电脑配置是...

图像研究猿的专栏 1391

python包安装——Swig

1、什么是swig SWIG 是一个非常优秀的开源工具,支持您将 C/C++ 代码与任何主流脚本语言相集成。此外,它向更广泛的受众公开了基本代码,改善了可测试性,让您的 Ruby 代码库某部分能快速写出高性能的 C/C++ 模块。 2、SWIG安装 到官网下载swigwin文件包,解压到一个文件夹中; 解压的文件夹中有个swig.exe文件,把该文件的路径添加到系统路径Pa

u014689510的博客 7978

swig封装c++成Python,兼容所有python3

解决swig封装Python3无法兼容所有Python3的问题。同时提供解决swig兼容Python2和Python3的封装问题。

x_yz_的专栏 1697

swig封装c++,编译为python初步应用

swig 本质上是个代码生成器,生成其他语言的包装代码(wrapper code),包装代码能够利用相应的 C API,因此就可以在其他语言中调用c++了。逻辑和算法是独立于语言的,因此理论上可以将所有的语言混合使用,因为其基本的逻辑和算法相同。那么将语言混合使用的关键在于什么,数据的传输,也就是数据在不同的语言之间怎么转换,这将是编程的关键。因此想要使用swig,就要写好考虑三个方面,1 c++的实现,2 python的应用,3 swig接口文件的构建,将二者进行连接。swig接口描述稳文件...

fengyun0909的博客 1310
上一篇: 用sscanf判断ip地址的正确性
下一篇: 最近在用python做一些东西,所以随便先写一下,后面慢慢补上
matlab2000
博客等级 码龄24年 37粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值