随笔 - 272  文章 - 0  评论 - 283  阅读 - 142万

使用c/c++扩展python

用python脚本写应用比较方便,但有时候由于种种原因需要扩展python(比如给程序提供python接口等)。 之前一直想整理下,今天终于坐下来把这件事情给做了,这里记录下,也方便我以后查阅。

说明: 测试环境中操作系统为CentOS6.5_x64,python版本为2.6

直接调用动态库

1、编写模块动态库文代码

这里以求最大数为示例

代码(callTest1.cpp)如下:

extern "C"
{
    int Max(int i1,int i2)
    {
        return (i1>i2)?i1:i2;
    }
}  

在bash中执行以下命令:

g++ -fPIC -shared -o libcallTest1.so callTest1.cpp

生成动态库文件libcallTest1.so

2、使用python调用动态库

可以通过ctypes调用动态库文件,具体如下:

#! /usr/bin/env python

from ctypes import *
import os

so1 = CDLL(os.getcwd() + '/libcallTest1.so')
print so1.Max(1,3)

使用boost库扩展python

这种方式可以直接生成python模块,使用import操作直接导入即可。 当然使用这种方式,需要安装boost库,具体操作这里就不说了,不懂的朋友自己查下。

boost官网:http://www.boost.org/

1、模块代码如下:

文件名:boostCallTest1.cpp

文件内容:

复制代码
int Max(int i1,int i2)
{
    return (i1>i2)?i1:i2;
}

#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
using namespace boost::python;

BOOST_PYTHON_MODULE(boostCallTest1)
{
    def("Max",Max);
}
复制代码

2、编写模块编译脚本

文件名: setup.py

文件内容:

复制代码
#!/usr/bin/env python

from distutils.core import setup
from distutils.extension import Extension

setup(name="PackageName",
    ext_modules=[
    Extension("boostCallTest1", ["boostCallTest1.cpp"],
    libraries = ["boost_python"])
])
复制代码

3、编译模块并测试

编译模块:

python setup.py build

会在build目录产生boostCallTest1.so文件,进入该目录,可如下使用:

>>> import boostCallTest1
>>> boostCallTest1.Max(1,3)
3

使用swig扩展python

SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。

SWIG能应用于各种不同类型的语言包括常用脚本编译语言例如Perl, PHP, Python, Tcl, Ruby and PHP。

swig官网: http://www.swig.org/download.html

可以通过yum直接安装:

yum install swig

1、编写程序代码

文件名:swigCall.cpp

内容如下:

int Max(int i1,int i2)
{
    return (i1>i2)?i1:i2;
}

2、编写接口文件

文件名:swigCall.i

内容如下:

%module swigCall
%{
extern int Max(int i1,int i2);
%}

extern int Max(int i1,int i2);

3、编写Makefile文件

内容如下:

复制代码
all:
        make swigCall

swigCall:
        swig -python -c++ swigCall.i
        g++ -c swigCall.cpp swigCall_wrap.cxx -I/usr/include/python2.7/ -fPIC
        g++ -shared swigCall.o swigCall_wrap.o -o _swigCall.so

clean:
        rm -f swigCall_wrap.c*
        rm -f *.py*
        rm -f *.so
        rm -f *.o
复制代码

注意:swig命令中要使用-c++参数编译c++代码

使用如下:

>>> import swigCall
>>> swigCall.Max(1,5)
5
>>>

使用SIP扩展python

SIP是从SWIG发展而来,专为Python调用C/C++模块使用的。 注意,这里的SIP和voip中的sip不是同一个东西,这里的sip是扩展python用的,voip中的sip是一个通信协议,不要搞混了。

注意:

需要安装python sip库;

1、编写c++模块

1.1 编写头文件

文件名: sipCall.h 文件内容:

class TestMode
{
public:  
    int Max(int i1,int i2);
}; 

1.2 编写模块内容

文件名:sipCall.cpp 文件内容:

#include "sipCall.h"  

int TestMode::Max(int i1,int i2)
{
    return (i1>i2)?i1:i2;
}

2、编写接口文件

文件名:sipCall.sip 文件内容:

%Module TestMode

class TestMode {  

%TypeHeaderCode  
#include "sipCall.h"  
%End  

public:  
    int Max(int i1,int i2);
};  

3、生存静态库

这里用脚本实现,文件名称:genlib.sh

文件内容:

#! /bin/bash
g++ -c -fPIC sipCall.cpp
ar -crs libsipCall.a sipCall.o

4、编写configure文件

该脚本用于生成Makefile,内容如下:

复制代码
#! /usr/bin/env python

import os  
import sipconfig  

build_file = "sipCall.sbf"
config = sipconfig.Configuration()
cmd = " ".join([config.sip_bin, "-c", ".", "-b", build_file, "sipCall.sip"])  
os.system(cmd)  

makefile = sipconfig.SIPModuleMakefile(config, build_file)
makefile.extra_libs = ["sipCall"]  
makefile.LIBDIR.append(".")  
makefile.generate()  
复制代码

5、运行genlib.sh脚本生成lib文件;

6、运行configure.py脚本生成Makefile;

7、运行make生成模块文件(so文件);

8、python测试如下:

>>> import TestMode
>>> dir(TestMode)
['TestMode', '__doc__', '__file__', '__name__', '__package__']
>>> s = TestMode.TestMode()
>>> s.Max(1,3)
3 

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2015/20150808_用c++扩展python.md

欢迎补充

posted on   Mike_Zhang  阅读(4239)  评论(2编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· DeepSeek “源神”启动!「GitHub 热点速览」
· 上周热点回顾(2.17-2.23)
历史上的今天:
2012-08-08 流媒体技术笔记(DarwinStreamingServer相关)
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

点击右上角即可分享
微信分享提示