(原)python使用ctypes调用C/C++接口
转载请注明出处:
http://www.cnblogs.com/darkknightzh/p/6135514.html
参考网址:
https://docs.python.org/2/library/ctypes.html——ctypes的官方文档
http://eli.thegreenplace.net/2008/08/31/ctypes-calling-cc-code-from-python/——提供了一个不涉及类的例子
http://stackoverflow.com/questions/145270/calling-c-c-from-python——建议使用ctypes,并提供了一个简单的例子
http://stackoverflow.com/questions/7142169/pils-image-frombuffer-expected-data-length-when-using-ctypes-array——提供了HYRY直接使用c_ubyte进行处理的例子
import Image
from ctypes import c_ubyte, cast, POINTER buf = (c_ubyte * 400)()
pbuf = cast(buf, POINTER(c_ubyte))
pbuf2 = cast(pbuf, POINTER(c_ubyte*400))
buf is an ubyte array, pbuf is a pointer to ubyte, pbuf2 is a pointer to ubyte[400]. img1 is created from buf directly, img2 is created from pubf2.contents.
http://www.linuxidc.com/Linux/2011-10/44838.htm——传结构体的简单例子
一 传简单的指针:
具体步骤:
1. 新建mathBuf.cpp:
#include <iostream>
#include "subBuf.h" extern "C"
{
int addBuf(char* data, int num, char* outData); subBuf* subBuf_new(){ return new subBuf(); }
int subBuf_sub(subBuf* subfuf, char* data, int num, char* outData){ subfuf->cursubBuf(data, num, outData); }
} int addBuf(char* data, int num, char* outData)
{
for (int i = ; i < num; ++i)
{
outData[i] = data[i] + ;
}
return num;
}
2. 新建subBuf.h:
#include <iostream> class subBuf{
public:
subBuf(){}
int cursubBuf(char* data, int num, char* outData)
{
for (int i = ; i < num; ++i)
{
outData[i] = data[i] - ;
}
return num;
}
};
3. 终端中输入如下命令,生成libmathBuf.so:
g++ -std=c++ -shared -fPIC -o libmathBuf.so mathBuf.cpp
4. 新建test.py:
from ctypes import * # cdll, c_int
lib = cdll.LoadLibrary('libmathBuf.so') class callsubBuf(object):
def __init__(self):
self.obj = lib.subBuf_new() def callcursubBuf(self, data, num, outData):
lib.subBuf_sub(self.obj, data, num, outData) callAddBuf = lib.addBuf num = 4
numbytes = c_int(num) data_in = (c_byte * num)()
for i in range(num):
data_in[i] = i print("initial input data buf:")
for i in range(num):
print(data_in[i]) #pdata_in = cast(data_in, POINTER(c_ubyte))
#pdata_in2 = cast(pdata_in, POINTER(c_ubyte*num)) data_out = (c_byte * num)() ret = callAddBuf(data_in, numbytes, data_out) print("after call addBuf with C, output buf:")
for i in range(num):
print(data_out[i]) f = callsubBuf()
f.callcursubBuf(data_in, numbytes, data_out) print("after call cursubBuf with C++ class, output buf:")
for i in range(num):
print(data_out[i])
5. 运行test.py,输出如下:
说明:
1) test.py如果使用c_byte,则对应C中的unsigned char。
2) 程序使用了2个文件,subBuf.h和mathBuf.cpp。实际上可以使用一个文件,但是class要在extern "C"的上面,否则即便声明了class subBuf,也会提示invalid use of incomplete type ‘class subBuf’:
3) addSub函数的实现要在extern "C"的下面,否则会提示error: conflicting declaration of XXX with ‘C’ linkage:
4) ctypes中对应的c和python类型如下(具体参见ctypes的官方文档):
ctypes type |
C type |
Python type |
c_bool |
_Bool |
bool (*) |
c_char |
char |
1-character string |
c_wchar |
wchar_t |
1-character unicode string |
c_byte |
char |
int/long |
c_ubyte |
unsigned char |
int/long |
c_short |
short |
int/long |
c_ushort |
unsigned short |
int/long |
c_int |
int |
int/long |
c_uint |
unsigned int |
int/long |
c_long |
long |
int/long |
c_ulong |
unsigned long |
int/long |
c_longlong |
__int64 or long long |
int/long |
c_ulonglong |
unsigned __int64 or unsigned long long |
int/long |
c_float |
float |
float |
c_double |
double |
float |
c_longdouble |
long double |
float |
c_char_p |
char * (NUL terminated) |
string or None |
c_wchar_p |
wchar_t * (NUL terminated) |
unicode or None |
c_void_p |
void * |
int/long or None |
*. The constructor accepts any object with a truth value.
5) 除此之外:
http://blog.csdn.net/tobacco5648/article/details/41083369
提供了使用void*传递缓冲区的简单说明。
二 传结构体
1. 新建structPoint.cpp:
#include <stdio.h>
#include <stdlib.h> struct structImg
{
int width;
int height;
int channels;
char* buf;
}; extern "C"
{
void showStructureInfo(structImg p);
} void showStructureInfo(structImg p)
{
printf("%d %d %d\n", p.width, p.height, p.channels);
for(int i=;i< p.width*p.height*p.channels; ++i)
printf("%d: %d\n", i, p.buf[i]);
}
2. 终端中将该文件编译成.so库:
g++ -std=c++ -shared -fPIC -o libstructPoint.so structPoint.cpp
3. 新建test.py:
from ctypes import *
lib = cdll.LoadLibrary('libstructPoint.so') class structImgTest(Structure):
_fields_ =[('width', c_int),
('height', c_int),
('channels', c_int),
('buf', POINTER(c_ubyte))] def getstructImg(width, height, channels):
#cwidth = c_int(width)
#cheight = c_int(height)
#cchannels = c_int(channels)
num = width * height * channels
data_buf = (c_byte * num)()
for i in range(num):
data_buf[i] = i pbuf = cast(data_buf, POINTER(c_ubyte)) st = structImgTest(width, height, channels, pbuf)
return st width = 4
height = 3
channels = 2
st = getstructImg(width, height, channels) callTest = lib.showStructureInfo
callTest(st) print st.width
print st.height # if declaration of test is test(structImg* p), then use the following line
pst = pointer(st) # not sure if "POINTER" points to ctypes type, while "pointer" points to a variable print pst.contents.width
print pst.contents.height
4. 终端中运行test.py,结果如下:
可见输出的结果正确。
=========================================================================
190130更新:
下面两个网址有使用ctypes的比较详细的说明,也可以参考一下。
https://cvstuff.wordpress.com/2014/11/20/wraping-c-code-with-python-ctypes-the-python-side/
https://cvstuff.wordpress.com/2014/11/27/wraping-c-code-with-python-ctypes-memory-and-pointers/
190130更新结束
=========================================================================
(原)python使用ctypes调用C/C++接口的更多相关文章
- Python 使用ctypes调用 C 函数
在python中通过ctypes可以直接调用c的函数,非常简单易用 下面就一步一步解释用法吧,以Linux为例讲解. 1, 首先确定你的python支持不支持ctypes python2.7以后cty ...
- python录音并调用百度语音识别接口
#!/usr/bin/env python import requests import json import base64 import pyaudio import wave import os ...
- python调用支付宝支付接口
python调用支付宝支付接口详细示例—附带Django demo代码 项目演示: 一.输入金额 二.跳转到支付宝付款 三.支付成功 四.跳转回自己网站 在使用支付宝接口的前期准备: 1.支付宝公 ...
- python调用C语言接口
python调用C语言接口 注:本文所有示例介绍基于linux平台 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题 ...
- 关于python调用zabbix api接口
因公司业务需要,引进了自动化运维,所用到的监控平台为zbbix3.2,最近正在学习python,计划使用python调用zabbix api接口去做些事情,如生成报表,我想最基本的是要取得zabbix ...
- python接口自动化(三十五)-封装与调用--流程类接口关联(详解)
简介 流程相关的接口,主要用 session 关联,如果写成函数(如上篇),s 参数每个函数都要带,每个函数多个参数,这时候封装成类会更方便.在这里我们还是以博客园为例,带着小伙伴们实践一下. 接口封 ...
- python - jpype模块,python调用java的接口
转载自: http://www.cnblogs.com/junrong624/p/5278457.html https://www.cnblogs.com/fanghao/p/7745356.html ...
- python 程序中调用go
虽然python优点很多,但是有一个致命的缺点就是运行速度太慢,那么python程序需要一些计算量比较大的模块时一般会调用c或者c++的代码来重写,但是c/c++编写代码代价太高,耗费太多的人力.那么 ...
- Python用Django写restful api接口
用Python如何写一个接口呢,首先得要有数据,可以用我们在网站上爬的数据,在上一篇文章中写了如何用Python爬虫,有兴趣的可以看看: https://www.cnblogs.com/sixrain ...
随机推荐
- PHP自定义弹出消息类,用于弹出提示信息并返回
一个用PHP自写的弹出消息类,用于在程序出错时弹出提示,,弹出警告框,或在程序运行到某阶段的快捷提示,需用时只需传入参数即可,函数并不复杂,但觉得挺实用.具体代码: function Alert($a ...
- discuz 万能SQL查询调用语句写法
首先在最底层source\class\table写入底层安全调用文件例如:table_common_friendlink.php 代码: <?php /** * [Discuz!] (C)200 ...
- memcache分布式小实例
<?php /** * 分布式的 memcache set 实现 */ /** * 创建缓存实现memcache 添加分布式服务器 并设置权限 */ function createCache() ...
- 信息安全实验二:return-to-libc
title: return-to-libc date: 2016-01-11 17:40:30 categories: information-security tags: return-to-lib ...
- wifi钓鱼教程
关于 <原创>想钓鱼必须还要有好竿wifi学习教程+软件下载地址修正 因为最近网盘维护 导致资源无法下载 今天早上开通下载服务了大家可以放心下载. 蹭网要低调不要炫耀 软件介绍:Wires ...
- OpenSSL初瞻及本系列的博文的缘由
OpenSSL初瞻及本系列的博文的缘由1.为什么要写关于“OpenSSL源码分析与学习笔记”系列博文?非常重要的两个原因是Heartbleed和学校课程.我虽然是一个非常崇尚自学的人但是并不代表我不擅 ...
- 小脚本一则---CDH的批量部署中,如果是从ESXI的VCENTER的模板生成的虚拟机,如何快速搞定网络网络卡配置?
当然,在作模板的过程中,我们除了要定义好SELINUX,IPTABLES之后, HOSTS文件维护,用ZOOKEEPER还是RSYNC实现? 都要在前期好好规划.. 脚本如下,一般改成自己的就可以用. ...
- 51单片机C语言学习笔记8:单片机C51编程规范
1.单片机C51编程规范- 前言 为了提高源程序的质量和可维护性,从而最终提高软件产品生产力,特编写此规范. 2.单片机C51编程规范-范围 本标准规定了程序设计人员进行程序设计时必须遵循的规范.本 ...
- 包含无数好东西的ownCloud
ownCloud 是一个来自 KDE 社区开发的免费软件,提供私人的 Web 服务.当前主要功能包括文件管理(内建文件分享).音乐.日历.联系人等等,可在PC和服务器上运行. 简单来说就是一个基于Ph ...
- QT 让窗口(或控件)居中
代码如下: XXX::XXX(QWidget *parent /* = 0 */) { .................. //注意,resize一定要放在这段代码的前面 resize(300, 3 ...