python与C、C++混编的四种方式(小结)


Posted in Python onJuly 15, 2019

混编的含义有两种,

一种是在python里面写C

一种是C里面写python

本文主要是进行简化,方便使用。

#####################################################################################################

第一种、Python调用C动态链接库(利用ctypes)

pycall.c

/***gcc -o libpycall.so -shared -fPIC pycall.c*/ 
#include <stdio.h> 
#include <stdlib.h> 
int foo(int a, int b) 
{ 
 printf("you input %d and %d\n", a, b); 
 return a+b; 
}

pycall.py

import ctypes 
ll = ctypes.cdll.LoadLibrary  
lib = ll("./libpycall.so")  
lib.foo(1, 3) 
print '***finish***'

运行方法:

gcc -o libpycall.so -shared -fPIC pycall.c
python pycall.py

第2种、Python调用C++(类)动态链接库(利用ctypes)

pycallclass.cpp

#include <iostream> 
using namespace std; 
 
class TestLib 
{ 
  public: 
    void display(); 
    void display(int a); 
}; 
void TestLib::display() { 
  cout<<"First display"<<endl; 
} 
 
void TestLib::display(int a) { 
  cout<<"Second display:"<<a<<endl; 
} 
extern "C" { 
  TestLib obj; 
  void display() { 
    obj.display();  
   } 
  void display_int() { 
    obj.display(2);  
   } 
}

pycallclass.py

import ctypes 
so = ctypes.cdll.LoadLibrary  
lib = so("./libpycallclass.so")  
print 'display()' 
lib.display() 
print 'display(100)' 
lib.display_int(100)

运行方法:

g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp
python pycallclass.py

第3种、Python调用C和C++可执行程序

main.cpp

#include <iostream> 
using namespace std; 
int test() 
{ 
  int a = 10, b = 5; 
  return a+b; 
} 
int main() 
{ 
  cout<<"---begin---"<<endl; 
  int num = test(); 
  cout<<"num="<<num<<endl; 
  cout<<"---end---"<<endl; 
}

main.py

import commands 
import os 
main = "./testmain" 
if os.path.exists(main): 
  rc, out = commands.getstatusoutput(main) 
  print 'rc = %d, \nout = %s' % (rc, out) 
 
print '*'*10 
f = os.popen(main)  
data = f.readlines()  
f.close()  
print data 
 
print '*'*10 
os.system(main)

运行方法(只有这种不是生成.so然后让python文件来调用):

g++ -o testmain main.cpp
python main.py

第4种、扩展Python(C++为Python编写扩展模块)(超级麻烦的一种)

Extest2.c

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
 
int fac(int n) 
{ 
  if (n < 2) return(1); 
  return (n)*fac(n-1); 
} 
 
char *reverse(char *s) 
{ 
  register char t, 
      *p = s, 
      *q = (s + (strlen(s) - 1)); 
 
  while (s && (p < q)) 
  { 
    t = *p; 
    *p++ = *q; 
    *q-- = t; 
  } 
  return(s); 
} 
 
int test() 
{ 
  char s[BUFSIZ]; 
  printf("4! == %d\n", fac(4)); 
  printf("8! == %d\n", fac(8)); 
  printf("12! == %d\n", fac(12)); 
  strcpy(s, "abcdef"); 
  printf("reversing 'abcdef', we get '%s'\n", \ 
    reverse(s)); 
  strcpy(s, "madam"); 
  printf("reversing 'madam', we get '%s'\n", \ 
    reverse(s)); 
  return 0; 
} 
 
#include "Python.h" 
 
static PyObject * 
Extest_fac(PyObject *self, PyObject *args) 
{ 
  int num; 
  if (!PyArg_ParseTuple(args, "i", &num)) 
    return NULL; 
  return (PyObject*)Py_BuildValue("i", fac(num)); 
} 
 
static PyObject * 
Extest_doppel(PyObject *self, PyObject *args) 
{ 
  char *orig_str; 
  char *dupe_str; 
  PyObject* retval; 
 
  if (!PyArg_ParseTuple(args, "s", &orig_str)) 
    return NULL; 
  retval = (PyObject*)Py_BuildValue("ss", orig_str, 
    dupe_str=reverse(strdup(orig_str))); 
  free(dupe_str);       
  return retval; 
} 
 
static PyObject * 
Extest_test(PyObject *self, PyObject *args) 
{ 
  test(); 
  return (PyObject*)Py_BuildValue(""); 
} 
 
static PyMethodDef 
ExtestMethods[] = 
{ 
  { "fac", Extest_fac, METH_VARARGS }, 
  { "doppel", Extest_doppel, METH_VARARGS }, 
  { "test", Extest_test, METH_VARARGS }, 
  { NULL, NULL }, 
}; 
 
void initExtest() 
{ 
  Py_InitModule("Extest", ExtestMethods); 
}

setup.py

#!/usr/bin/env python 
 
from distutils.core import setup, Extension 
 
MOD = 'Extest' 
setup(name=MOD, ext_modules=[Extension(MOD, sources=['Extest2.c'])])

运行方法:

python setup.py build
cd build/lib.linux-x86_64-2.7

进入python交互模式>>>

import Extest
Extest.test()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现搜索本地文件信息写入文件的方法
Feb 22 Python
K-means聚类算法介绍与利用python实现的代码示例
Nov 13 Python
python实现单向链表详解
Feb 08 Python
Pandas 同元素多列去重的实例
Jul 03 Python
python3.6利用pyinstall打包py为exe的操作实例
Oct 31 Python
Python判断一个文件夹内哪些文件是图片的实例
Dec 07 Python
解决django后台样式丢失,css资源加载失败的问题
Jun 11 Python
使用selenium和pyquery爬取京东商品列表过程解析
Aug 15 Python
python对Excel的读取的示例代码
Feb 14 Python
详解pyinstaller生成exe的闪退问题解决方案
Jun 19 Python
利用python爬取有道词典的方法
Dec 08 Python
Python3利用openpyxl读写Excel文件的方法实例
Feb 03 Python
解决Python3 控制台输出InsecureRequestWarning问题
Jul 15 #Python
python导包的几种方法(自定义包的生成以及导入详解)
Jul 15 #Python
Python将文字转成语音并读出来的实例详解
Jul 15 #Python
解决win7操作系统Python3.7.1安装后启动提示缺少.dll文件问题
Jul 15 #Python
Python符号计算之实现函数极限的方法
Jul 15 #Python
在python 中split()使用多符号分割的例子
Jul 15 #Python
Python-Seaborn热图绘制的实现方法
Jul 15 #Python
You might like
详解php魔术方法(Magic methods)的使用方法
2016/02/14 PHP
PHP redis实现超迷你全文检索
2017/03/04 PHP
PHP实现通过文本文件统计页面访问量功能示例
2019/02/13 PHP
漂亮的仿flash菜单,来自蓝色经典
2006/06/26 Javascript
js几个不错的函数 $$()
2006/10/09 Javascript
use jscript with List Proxy Server Information
2007/06/11 Javascript
基于jquery自定义图片热区效果
2012/07/21 Javascript
JS中Location使用详解
2015/05/12 Javascript
解析Node.js基于模块和包的代码部署方式
2016/02/16 Javascript
基于jQuery实现的无刷新表格分页实例
2016/02/17 Javascript
jQuery增加与删除table列的方法
2016/03/01 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
温习Javascript基础语法之词法结构
2016/05/31 Javascript
详解Vue2+Echarts实现多种图表数据可视化Dashboard(附源码)
2017/03/21 Javascript
angular使用post、get向后台传参的问题实例
2017/05/27 Javascript
Angular HMR(热模块替换)功能实现方法
2018/04/04 Javascript
Mint UI组件库CheckList使用及踩坑总结
2018/12/20 Javascript
vue ssr 实现方式(学习笔记)
2019/01/18 Javascript
js实现掷骰子小游戏
2019/10/24 Javascript
详解如何修改 node_modules 里的文件
2020/05/22 Javascript
vue2.* element tabs tab-pane 动态加载组件操作
2020/07/19 Javascript
JavaScript canvas实现雨滴特效
2021/01/10 Javascript
python之wxPython菜单使用详解
2014/09/28 Python
跟老齐学Python之从格式化表达式到方法
2014/09/28 Python
TensorFlow入门使用 tf.train.Saver()保存模型
2018/04/24 Python
Python3.5 创建文件的简单实例
2018/04/26 Python
django ManyToManyField多对多关系的实例详解
2019/08/09 Python
如何基于Python制作有道翻译小工具
2019/12/16 Python
python多进程使用函数封装实例
2020/05/02 Python
python3.7添加dlib模块的方法
2020/07/01 Python
支票、地址标签、包装纸和慰问卡:Current Catalog
2018/01/30 全球购物
在C++ 程序中调用被C 编译器编译后的函数,为什么要加extern "C"
2014/08/09 面试题
行政管理专业求职信
2014/07/06 职场文书
大学生就业意向书
2015/05/11 职场文书
演讲比赛通讯稿
2015/07/18 职场文书
党组织结对共建协议书
2016/03/23 职场文书