使用C语言扩展Python(四)
INBUFSIZE = 4096
if __name__ == '__main__':
encoder = clame.Encoder('test.mp3')
input = file('test.raw', 'rb')
data = input.read(INBUFSIZE)
while data != '':
encoder.encode(data)
data = input.read(INBUFSIZE)
input.close()
encoder.close()
再来看C扩展模块这一端,下面是完整的代码:
#include <lame.h>
typedef struct {
PyObject_HEAD
FILE* outfp;
lame_global_flags* gfp;
}clame_EncoderObject;
static PyObject* Encoder_new(PyTypeObject* type, PyObject* args, PyObject* kw) {
clame_EncoderObject* self = (clame_EncoderObject* )type->tp_alloc(type, 0);
self->outfp = NULL;
self->gfp = NULL;
return (PyObject*)self;
}
static void Encoder_dealloc(clame_EncoderObject* self) {
if (self->gfp) {
lame_close(self->gfp);
}
if (self->outfp) {
fclose(self->outfp);
}
self->ob_type->tp_free(self);
}
static int Encoder_init(clame_EncoderObject* self, PyObject* args, PyObject* kw) {
char* outPath;
if (!PyArg_ParseTuple(args, "s", &outPath)) {
return -1;
}
if (self->outfp || self->gfp) {
PyErr_SetString(PyExc_Exception, "__init__ already called");
return -1;
}
self->outfp = fopen(outPath, "wb");
self->gfp = lame_init();
lame_init_params(self->gfp);
return 0;
}
static PyObject* Encoder_encode(clame_EncoderObject* self, PyObject* args) {
char* in_buffer;
int in_length;
int mp3_length;
char* mp3_buffer;
int mp3_bytes;
if (!(self->outfp || self->gfp)) {
PyErr_SetString(PyExc_Exception, "encoder not open");
return NULL;
}
if (!PyArg_ParseTuple(args, "s#", &in_buffer, &in_length)) {
return NULL;
}
in_length /= 2;
mp3_length = (int)(1.25 * in_length) + 7200;
mp3_buffer = (char*)malloc(mp3_length);
if (in_length > 0) {
mp3_bytes = lame_encode_buffer_interleaved(self->gfp, (short*)in_buffer, in_length/2, mp3_buffer, mp3_length);
if (mp3_bytes > 0) {
fwrite(mp3_buffer, 1, mp3_bytes, self->outfp);
}
}
free(mp3_buffer);
Py_RETURN_NONE;
}
static PyObject* Encoder_close(clame_EncoderObject* self) {
int mp3_length;
char* mp3_buffer;
int mp3_bytes;
if (!(self->outfp && self->gfp)) {
PyErr_SetString(PyExc_Exception, "encoder not open");
return NULL;
}
mp3_length = 7200;
mp3_buffer = (char*)malloc(mp3_length);
mp3_bytes = lame_encode_flush(self->gfp, mp3_buffer, sizeof(mp3_buffer));
if (mp3_bytes > 0) {
fwrite(mp3_buffer, 1, mp3_bytes, self->outfp);
}
free(mp3_buffer);
lame_close(self->gfp);
self->gfp = NULL;
fclose(self->outfp);
self->outfp = NULL;
Py_RETURN_NONE;
}
static PyMethodDef Encoder_methods[] = {
{"encode", (PyCFunction)Encoder_encode, METH_VARARGS, "encodes and writes data to the output file."},
{"close", (PyCFunction)Encoder_close, METH_NOARGS, "close the output file."},
{NULL, NULL, 0, NULL}
};
static PyTypeObject clame_EncoderType = {
PyObject_HEAD_INIT(NULL)
0, // ob_size
"clame.Encoder", // tp_name
sizeof(clame_EncoderObject), // tp_basicsize
0, // tp_itemsize
(destructor)Encoder_dealloc, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
"My first encoder object.", // tp_doc
0, // tp_traverse
0, // tp_clear
0, // tp_richcompare
0, // tp_weaklistoffset
0, // tp_iter
0, // tp_iternext
Encoder_methods, // tp_methods
0, // tp_members
0, // tp_getset
0, // tp_base
0, // tp_dict
0, // tp_descr_get
0, // tp_descr_set
0, // tp_dictoffset
(initproc)Encoder_init, // tp_init
0, // tp_alloc
Encoder_new, // tp_new
0, // tp_free
};
static PyMethodDef clame_methods[] = {
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initclame() {
PyObject* m;
if (PyType_Ready(&clame_EncoderType) < 0) {
return;
m = Py_InitModule3("clame", clame_methods, "My second lame module.");
Py_INCREF(&clame_EncoderType);
PyModule_AddObject(m, "Encoder", (PyObject*) &clame_EncoderType);
}
编译过程:
首先定义了clame_EncoderObject结构体,这个结构体就是用来存储状态信息的,字段outfp用来存储输出文件,gfp则保存lame的状态,可以用来检查是否已经是重复调用已经调用过的函数了。
为了创建这个结构体的一个新实例,我们需要定义Encoder_new函数,你可以把这个函数视为Python里的__new__方法,当Python解释器需要创建你定义的类型的新实例时就会去调用这个方法。在这个方法里没作什么操作,仅仅是做初始化工作,把outfp和gfp都设置为NULL,此外,与Encoder_new函数对应,还需要定义Encoder_dealloc方法来对实例进行析构,你可以把这个函数视为Python的__del__方法,clame_EncoderType结构体则是真正定义了我们的Encoder对象,它的各个字段指定了_new,_close,_encode,_dealloc等方法。在initclame方法中,PyModuleObject则实际指定了在Python程序中使用的Encoder对象。
使用C语言扩展Python(四)相关推荐
- 用C语言扩展Python的功能的实例
用C语言扩展Python的功能的实例 分类: C/C++ 编程技巧 Programes 2008-04-23 09:31 1232人阅读 评论(0)收藏 举报 python扩展语言cmethodsnu ...
- python代码用c语言封装_使用C语言扩展Python程序的简单入门指引
一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且还表现在其良好的可扩展性上,正因如此,Python已经开始受到越来越多人的青睐,并且被屡屡成功地应用于各类大型 ...
- c语言实现python语法_用C语言扩展Python的功能
转自:http://www.ibm.com/developerworks/cn/linux/l-pythc/ 一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且 ...
- 如何将c语言程序封装供python调用_转:用C语言扩展Python的功能
一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且还表现在其良好的可扩展性上,正因如此,Python已经开始受到越来越多人的青睐,并且被屡屡成功地应用于各类大型 ...
- c语言转换为python语言_【转】用C语言扩展Python的功能
一.简介 Python是一门功能强大的高级脚本语言,它的强大不仅表现在其自身的功能上,而且还表现在其良好的可扩展性上,正因如此,Python已经开始受到越来越多人的青睐,并且被屡屡成功地应用于各类大型 ...
- python安装c语言库_C语言扩展Python模块
一. main.cpp #include #include "Python.h" static PyObject* Py_Add_Formular(PyObject *self, ...
- 使用C语言扩展Python(三)
上一篇中我们已经了解如何在Python程序和C模块之间进行值的相互传递,现在我们来进入实作阶段,看看如何将一个C语言开发的开源mp3编解码库LAME包装为一个Python下可以使用的扩展模块. 首先去 ...
- 用C语言扩展Python的功能
https://www.ibm.com/developerworks/cn/linux/l-pythc/
- python c 混合编程 用c循环_混合编程:用 C 语言来扩展 Python 大法吧!
Python 实在是一种让人上瘾的编程语言,简洁的语法+丰富的扩展包,几乎可以用 Python 做任何事情,唯一的黑点似乎就是「慢」,但是与高效的编译语言 C\C++ 互联以后,可以解决脚本语言运行速 ...
最新文章
- 源目标OKR— 在线团队协同办公、项目管理工具
- tensorflow checkpoint文件
- idea编译的jsp存在哪里
- <马哲>生产方式是社会发展的决定力量2017-12-27
- c++适配器模式adapter
- 使用CADisplayLink实现UILabel动画特效
- linux ntfs 速度慢,将U盘磁盘格式改成NTFS解决u盘复制速度慢问题
- 少儿编程100讲轻松学python(三)-python如何重命名文件
- UVA 10405-Longest Common Subsequence
- 判断应用程序在前台还是后台
- hung task日志linux,Linux Kernel Crash--hung_task_timeout_secs
- IIS服务器应用程序不可用的解决办法
- linux监控文件是否传输,利用SecureCRT在linux与Windows之间传输文件
- C学习的日志(随手记、随手写)
- [Kerberos基础]-- kerberos认证原理---讲的非常细致,易懂
- ios 设置控制器背景半透明_iOS Modal出半透明控制器
- NLP创业破局,如何摘取更高处的果实
- Android App软件框架搭建
- JAVA的人民币大写(金额)转化
- 论文笔记-DeepLung: Deep 3D Dual Path Nets for Automated Pulmonary Nodule Detection and Classification
热门文章
- c++基础学习(13)--(STL、标准库)
- 写出表格的结构html,一个面试题,根据json结构生成html表格
- gcc中的内嵌汇编语言(Intel i386平台)
- java - 通用 CRUD(增、删、改、查)工具类,代码高效复用
- linux 查看空间(内存、磁盘、文件目录、分区)的几个命令
- linux (阿里云 CentOS7) 中安装配置 RocketMQ
- String... 参数定义中有三个点的意思
- unexpected EOF while looking for matching ``‘
- 解决dataTable 报错:cannot read property “style“ of undefined
- Easyjs 细说Javascript里的 闭包(Closure)