python

超轻量级php框架startmvc

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

更新时间:2020-07-14 12:54:01 作者:startmvc
混编的含义有两种,一种是在python里面写C一种是C里面写python本文主要是进行简化,方便使

混编的含义有两种,

一种是在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 C、C++混编