编程中会遇到调用其他语言到库,这里记录一下Python调用C++。
Python底层是C, 所以调用C还是比较方便。调用C++有些麻烦。
Python提供了ctypes, 方便将Python类型转为C类型,实现传参数、函数返回类型的对应。ctypes网址:https://docs.python.org/2/library/ctypes.html
使用Python调用C/C++主要有三步:
(1) 编写好C/C++函数
(2) 把C/C++函数打包成库文件
(3) Python加载库文件并调用
代码记录一下:
1. pycall.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h> class PythonTest{
public:
PythonTest():_is_inited(false), _num(){ } int init(int num){
_num = num;
_is_inited = true;
printf("inited ok\n");
return ;
} int str2(char *src, char* dest, int len){
if (src == NULL || len <= ){
return ;
} int src_len = strlen(src);
int num = snprintf(dest, len, "%s%s", src, src);
return (num < len -)? num:;
} bool is_inited(){
printf("_num = %d\n", _num);
return _is_inited;
} private:
bool _is_inited;
int _num;
};
2. pycall_so.cpp
#include "pycall.h" extern "C" { PythonTest py; int init(int num){
return py.init(num);
} bool is_inited(){
return py.is_inited();
} int str2(char* src, char* dest, int len){
return py.str2(src, dest, len);
} int add(int a, int b){
return a + b;
} }
3. pycall.py
#coding=utf-8 import ctypes
from ctypes import * ##加载库文件
ll = ctypes.cdll.LoadLibrary
lib = ll("./libpycall.so") ##call
fun=lib.init ###类似C/C++函数指针
fun.restype = c_int ##设置函数返回值类型
print fun(8);
print "*" * 20 ##call
fun=lib.is_inited
fun.restype = c_bool
print fun();
print "*" * 20 ##call
fun=lib.str2
src = "hello world "
dest = "*" * 30 ###申请buf, 用于保存返回结果
num = fun(src, dest, len(dest)) ###传递指针作为参数
if num != 0:
print dest[:num]
else:
print "buf is not ok"
print "*" * 20 ##call
print lib.add(1, 2);
print "*" * 20
执行结果:
aaarticlea/png;base64,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" alt="" />