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

混编的含义有两种,

一种是在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()

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

(0)

相关推荐

  • 浅谈python和C语言混编的几种方式(推荐)

    Python这些年风头一直很盛,占据了很多领域的位置,Web.大数据.人工智能.运维均有它的身影,甚至图形界面做的也很顺,乃至full-stack这个词语刚出来的时候,似乎就是为了描述它. Python虽有GIL的问题导致多线程无法充分利用多核,但后来的multiprocess可以从多进程的角度来利用多核,甚至affinity可以绑定具体的CPU核,这个问题也算得到解决.虽基本为全栈语言,但有的时候为了效率,可能还是会去考虑和C语言混编.混编是计算机里一个不可回避的话题,涉及的东西很多,技术.架

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

    混编的含义有两种, 一种是在python里面写C 一种是C里面写python 本文主要是进行简化,方便使用. ##################################################################################################### 第一种.Python调用C动态链接库(利用ctypes) pycall.c /***gcc -o libpycall.so -shared -fPIC pycall.c*/ #inclu

  • PHP/HTML混写的四种方式总结

    PHP作为一款后端语言,为了输出给浏览器让浏览器呈现出来,无可避免的要输出HTML代码,下文介绍下我用过的三种PHP/HTML混编方法 1.单/双引号包围法 这是最初级的方法了,用法就像下面这样 <?php echo ' <!DOCTYPE html> <html> <head> <title> </title> </head> <body> <span>测试页面</span> </bo

  • python 实现socket服务端并发的四种方式

    多进程&多线程 服务端:多进程和多线程的开启方式相同. 缺点:<1> 由于Cpython的GIL,导致同一时间无法运行多个线程:<2> 不可能无限开进进程或线程 解决办法:多进程.concurrent.futures.ProcessPoolExecutor.线程池 import socket from multiprocessing import Process from threading import Thread class MyTcpServer: def __in

  • python设置 matplotlib 正确显示中文的四种方式

    一.前言 啪地一下点进来,很快呀~~ matplotlib是 Python 优秀的数据可视化第三方库,matplotlib是基于 numpy 的一套 Python 工具包.这个包提供了丰富的数据绘图工具,主要用于绘制一些统计图形. Matplotlib库由各种可视化类构成,内部结构复杂,受 Matlab 启发 matplotlib.pyplot 是绘制各类可视化图形的命令子库,相当于快捷方式. import matplotlib.pyplot as plt 可 matplotlib 并不支持中文

  • Python获取协程返回值的四种方式详解

    目录 介绍 源码 依次执行结果 介绍 获取协程返回值的四种方式: 1.通过ensure_future获取,本质是future对象中的result方 2.使用loop自带的create_task, 获取返回值 3.使用callback, 一旦await地方的内容运行完,就会运行callback 4.使用partial这个模块向callback函数中传入值 源码 import asyncio from functools import partial async def talk(name): pr

  • Laravel 实现Controller向blade前台模板赋值的四种方式小结

    如下所示: <?php namespace App\Http\Controllers; use Illuminate\Http\Request; class TestController extends Controller { public function show(){ return view('show',['name'=>'asdfasdfasdfa']); //方法一 是把数组里的键值对赋值过去了,blade模板里用键名来取,如{{$name}} {{$gender}} //方法二

  • 基于spring三方包类注入容器的四种方式小结

    如果引用第三方jar包,肯定是不能直接使用常用注解@Controller.@Service.@Repository.@Component将类的实例注入到spring容器中.以下四种方法可以向spring容器中导入三方包中类实例 . 1 xml配置 这种情况大家用的比较多,就是在spring的xml文件中配置需要导入的bean.在springweb项目工程web.xml中 ContextLoaderListener或者DispatcherServlet的初始参数contextConfigLocat

  • Springcloud+Mybatis使用多数据源的四种方式(小结)

    前段时间在做会员中心和中间件系统开发时,多次碰到多数据源配置问题,主要用到分包方式.参数化切换.注解+AOP.动态添加 这四种方式.这里做一下总结,分享下使用心得以及踩过的坑. 分包方式 数据源配置文件 在yml中,配置两个数据源,id分别为master和s1. spring: datasource: master: jdbcUrl: jdbc:mysql://192.168.xxx.xxx:xxxx/db1?......... username: xxx password: xxx drive

  • Spring中集成Groovy的四种方式(小结)

    groovy是一种动态脚本语言,适用于一些可变.和规则配置性的需求,目前Spring提供ScriptSource接口,支持两种类型,一种是 ResourceScriptSource,另一种是 StaticScriptSource,但是有的场景我们需要把groovy代码放进DB中,所以我们需要扩展这个. ResourceScriptSource:在 resources 下面写groovy类 StaticScriptSource:把groovy类代码放进XML里 DatabaseScriptSour

随机推荐