C扩展Python模块,实现地震数据的I/O
在Python进行应用开发时,为提升性能,需要使用C开发出Python模块,本文以地震数据I/O为例说明C开发模块方法,步骤。
1、工具
QT Creator4.2.1
在.pro文件中添加Python库,
INCLUDEPATH +=D:/Python36-32/include ############# python enviroment
LIBS += -LD:/Python36-32/libs \
-lpython36
2、编译器
MinGW5.3
3、模块开发
创建.C文件 seismicio.c
头文件包含如下:
#if defined(_DEBUG) && defined(_MSC_VER)
# define _CRT_NOFORCE_MAINFEST 1
# undef _DEBUG
# include <Python.h>
# include <bytesobject.h>
# define _DEBUG 1
#else
# include <Python.h>
# include <bytesobject.h>
#endif
定义segy数据相关结构
typedef struct {
PyObject_HEAD
PyObject* readbuf; //读取的数据缓存
PyObject* tracedatabuf; //一道数据缓存
PyObject* traceformat; /*240道头格式*/ // list[{dict},{dict}]
PyObject* h400format; //400文件头格式 list[{dict},{dict}]
#ifdef __cplusplus
seismic_file *fd;
#else
struct seismic_file *fd;
#endif
int samples;
int dt;
int tracelength;
long long tracecount;
}seismiciofd;
定义Python Seismiciofd对象
PyTypeObject Seismiciofd = {
PyVarObject_HEAD_INIT( NULL, 0 )
"_seismicio.seismicfd", /* name */
sizeof( seismiciofd ), /* basic size */
0, /* tp_itemsize */
(destructor)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 */
"segyio file descriptor", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
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)init, /* tp_init */
};
定义地震数据I/O模块对象
PyMethodDef SeismicMethods[] = {
// { "putfield", (PyCFunction) putfield, METH_VARARGS, "Put a header field." },
{ NULL }
};
模块初始化:
* module initialization */
#ifdef IS_PY3K
static struct PyModuleDef seismicio_module = {
PyModuleDef_HEAD_INIT,
"_seismicio", /* name of module */
NULL, /* module documentation, may be NULL */
-1, /* size of per-interpreter state of the module, or -1 if the module keeps state in global variables. */
SeismicMethods
};
PyMODINIT_FUNC
PyInit__seismicio(void) {
Seismiciofd.tp_new = PyType_GenericNew;
if( PyType_Ready( &Seismiciofd ) < 0 ) return NULL;
PyObject* m = PyModule_Create(&seismicio_module);
if( !m ) return NULL;
Py_INCREF( &Seismiciofd );
PyModule_AddObject( m, "seismiciofd", (PyObject*)&Seismiciofd );
return m;
}
#else
PyMODINIT_FUNC
init_seismicio(void) {
Segyiofd.tp_new = PyType_GenericNew;
if( PyType_Ready( &Seismiciofd ) < 0 ) return;
PyObject* m = Py_InitModule("_seismicio", SeismicMethods);
Py_INCREF( &Seismiciofd );
PyModule_AddObject( m, "seismiciofd", (PyObject*)&Seismiciofd );
}
#endif