首页 > 编程 > Python > 正文

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

2019-11-25 12:22:49
字体:
来源:转载
供稿:网友

混编的含义有两种,

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

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表