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