网络编程
位置:首页>> 网络编程>> Python编程>> python与C、C++混编的四种方式(小结)

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

作者:俞驰的博客  发布时间:2021-06-03 03:01:24 

标签: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()

来源:https://blog.csdn.net/appleyuchi/article/details/78540959

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com