python与C、C++混编的四种方式

来源:互联网 发布:oracle sql rowcount 编辑:程序博客网 时间:2024/06/02 19:26

混编的含义有两种,

一种是在python里面写C

一种是C里面写python

本文针对第一种,参考链接来自:

https://www.cnblogs.com/apexchu/p/5015961.html

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

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

第一种、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()



原创粉丝点击