Python调用C/C++的种种方法

简介:

Python是解释性语言, 底层就是用c实现的, 所以用python调用C是很容易的, 下面就总结一下各种调用的方法, 给出例子, 所有例子都在ubuntu9.10, python2.6下试过.

1. Python 调用 C (base)

想在python中调用c函数, 如这儿的fact

#include 

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

PyObject* wrap_fact(PyObject* self, PyObject* args)
{
  int n, result;

  if (! PyArg_ParseTuple(args, "i:fact", &n))
    return NULL;
  result = fact(n);
  return Py_BuildValue("i", result);
}

static PyMethodDef exampleMethods[] =
{
  {"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
  {NULL, NULL}
};

void initexample()
{
  PyObject* m;
  m = Py_InitModule("example", exampleMethods);
}

把这段代码存为wrapper.c, 编成so库,

gcc -fPIC wrapper.c -o example.so -shared  -I/usr/include/python2.6 -I/usr/lib/python2.6/config

然后在有此so库的目录, 进入python, 可以如下使用

import example

example.fact(4)

 

2. Python 调用 C++ (base)

在python中调用C++类成员函数, 如下调用TestFact类中的fact函数,

#include 

class TestFact{
    public:
    TestFact(){};
    ~TestFact(){};
    int fact(int n);
};

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

int fact(int n)
{
    TestFact t;
    return t.fact(n);
}

PyObject* wrap_fact(PyObject* self, PyObject* args)
{
  int n, result;

  if (! PyArg_ParseTuple(args, "i:fact", &n))
    return NULL;
  result = fact(n);
  return Py_BuildValue("i", result);
}

static PyMethodDef exampleMethods[] =
{
  {"fact", wrap_fact, METH_VARARGS, "Caculate N!"},
  {NULL, NULL}
};

extern "C"              //不加会导致找不到initexample
void initexample()
{
  PyObject* m;
  m = Py_InitModule("example", exampleMethods);
}

 

把这段代码存为wrapper.cpp, 编成so库,

g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

 

然后在有此so库的目录, 进入python, 可以如下使用

import example

example.fact(4)

 

3. Python 调用 C++ (Boost.Python)

Boost库是非常强大的库, 其中的python库可以用来封装c++被python调用, 功能比较强大, 不但可以封装函数还能封装类, 类成员.

http://dev.gameres.com/Program/Abstract/Building%20Hybrid%20Systems%20with%20Boost_Python.CHN.by.JERRY.htm

首先在ubuntu下安装boost.python, apt-get install libboost-python-dev

#include 
char const* greet()
{
   return "hello, world";
}

BOOST_PYTHON_MODULE(hello)
{
    using namespace boost::python;
    def("greet", greet);
}

把代码存为hello.cpp, 编译成so库

g++ hello.cpp -o hello.so -shared -I/usr/include/python2.5 -I/usr/lib/python2.5/config -lboost_python-gcc42-mt-1_34_1

此处python路径设为你的python路径, 并且必须加-lboost_python-gcc42-mt-1_34_1, 这个库名不一定是这个, 去/user/lib查

然后在有此so库的目录, 进入python, 可以如下使用

>>> import hello
>>> hello.greet()
'hello, world'

 

4. python 调用 c++ (ctypes)

ctypes is an advanced ffi (Foreign Function Interface) package for Python 2.3 and higher. In Python 2.5 it is already included.

ctypes allows to call functions in dlls/shared libraries and has extensive facilities to create, access and manipulate simple and complicated C data types in Python - in other words: wrap libraries in pure Python. It is even possible to implement C callback functions in pure Python.

http://python.net/crew/theller/ctypes/

#include 

class TestFact{
    public:
    TestFact(){};
    ~TestFact(){};
    int fact(int n);
};

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

extern "C"
int fact(int n)
{
    TestFact t;
    return t.fact(n);
}
将代码存为wrapper.cpp不用写python接口封装, 直接编译成so库,

g++ -fPIC wrapper.cpp -o example.so -shared -I/usr/include/python2.6 -I/usr/lib/python2.6/config

进入python, 可以如下使用

>>> import ctypes
>>> pdll = ctypes.CDLL('/home/ubuntu/tmp/example.so')
>>> pdll.fact(4)
12


本文章摘自博客园,原文发布日期:2011-07-05

寒凝雪
+关注
目录
打赏
0
0
0
0
176
分享
相关文章
|
21天前
|
时间序列异常检测:MSET-SPRT组合方法的原理和Python代码实现
MSET-SPRT是一种结合多元状态估计技术(MSET)与序贯概率比检验(SPRT)的混合框架,专为高维度、强关联数据流的异常检测设计。MSET通过历史数据建模估计系统预期状态,SPRT基于统计推断判定偏差显著性,二者协同实现精准高效的异常识别。本文以Python为例,展示其在模拟数据中的应用,证明其在工业监控、设备健康管理及网络安全等领域的可靠性与有效性。
550 13
时间序列异常检测:MSET-SPRT组合方法的原理和Python代码实现
Python 中调用 DeepSeek-R1 API的方法介绍,图文教程
本教程详细介绍了如何使用 Python 调用 DeepSeek 的 R1 大模型 API,适合编程新手。首先登录 DeepSeek 控制台获取 API Key,安装 Python 和 requests 库后,编写基础调用代码并运行。文末包含常见问题解答和更简单的可视化调用方法,建议收藏备用。 原文链接:[如何使用 Python 调用 DeepSeek-R1 API?](https://apifox.com/apiskills/how-to-call-the-deepseek-r1-api-using-python/)
|
7天前
|
[oeasy]python086方法_method_函数_function_区别
本文详细解析了Python中方法(method)与函数(function)的区别。通过回顾列表操作如`append`,以及随机模块的使用,介绍了方法作为类的成员需要通过实例调用的特点。对比内建函数如`print`和`input`,它们无需对象即可直接调用。总结指出方法需基于对象调用且包含`self`参数,而函数独立存在无需`self`。最后提供了学习资源链接,方便进一步探索。
44 17
uv安装python及其依赖的加速方法
国内在使用uv的时候,可能会涉及到装python的速度太慢的问题,为了解决这个问题,可以使用`UV_PYTHON_INSTALL_MIRROR`这个环境变量。除此以外,对于多人协作场景,`UV_CACHE_DIR`也是一个有用的环境变量。本文会介绍这两个变量。
73 9
从命名约定到特殊方法,Python下划线符号的妙用!
下划线(`_`)是Python开发者日常接触的重要符号,其含义和应用场景多样。本文全面解析了Python中下划线的不同用法,包括单下划线作为临时变量、国际化翻译函数、交互式解释器特殊变量;单下划线前缀表示保护成员;单下划线后缀避免关键字冲突;双下划线前缀触发名称改写;双下划线前后缀定义特殊方法等。此外,还介绍了数字分隔符、模式匹配通配符等新特性,并总结了下划线使用的最佳实践与常见问题解答。通过本文,读者可深入了解下划线在Python中的多重角色及其设计哲学。
42 2
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
76 12
随机的暴力美学蒙特卡洛方法 | python小知识
蒙特卡洛方法是一种基于随机采样的计算算法,广泛应用于物理学、金融、工程等领域。它通过重复随机采样来解决复杂问题,尤其适用于难以用解析方法求解的情况。该方法起源于二战期间的曼哈顿计划,由斯坦尼斯拉夫·乌拉姆等人提出。核心思想是通过大量随机样本来近似真实结果,如估算π值的经典示例。蒙特卡洛树搜索(MCTS)是其高级应用,常用于游戏AI和决策优化。Python中可通过简单代码实现蒙特卡洛方法,展示其在文本生成等领域的潜力。随着计算能力提升,蒙特卡洛方法的应用范围不断扩大,成为处理不确定性和复杂系统的重要工具。
130 21
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
83 10
Python中使用MySQL模糊查询的方法
本文介绍了两种使用Python进行MySQL模糊查询的方法:一是使用`pymysql`库,二是使用`mysql-connector-python`库。通过这两种方法,可以连接MySQL数据库并执行模糊查询。具体步骤包括安装库、配置数据库连接参数、编写SQL查询语句以及处理查询结果。文中详细展示了代码示例,并提供了注意事项,如替换数据库连接信息、正确使用通配符和关闭数据库连接等。确保在实际应用中注意SQL注入风险,使用参数化查询以保障安全性。
Python-打印99乘法表的两种方法
本文详细介绍了两种实现99乘法表的方法:使用`while`循环和`for`循环。每种方法都包括了步骤解析、代码演示及优缺点分析。文章旨在帮助编程初学者理解和掌握循环结构的应用,内容通俗易懂,适合编程新手阅读。博主表示欢迎读者反馈,共同进步。