Python ekstensi pemrograman dengan C

Hasil gambar untuk python

Setiap kode yang Anda menulis menggunakan dikompilasi bahasa seperti C, C++,atau Java dapat terintegrasi atau diimpor ke script Python yang lain. Kode ini dianggap sebagai "ekstensi."

Python ekstensi modul adalah tidak lebih daripada normal C library. Pada mesin Unix, Perpustakaan ini biasanya berakhir pada .so (untuk objek yang dibagi). Padamesin Windows, Anda biasanya melihat .dll (untuk perpustakaan yang terkait secara dinamis).


Pra-syarat untuk menulis ekstensi

Untuk mulai menulis ekstensi Anda, Anda akan perlu file header Python.


Pada mesin Unix, hal ini biasanya memerlukan menginstal paket pengembang-spesifik seperti python2.5-dev.

Pengguna Windows mendapatkan header ini sebagai bagian dari paket ketika mereka menggunakan installer biner Python.


Selain itu, hal ini diasumsikan bahwa Anda memiliki pengetahuan yang baik dalamC atau C++ untuk menulis Python perpanjangan menggunakan C pemrograman.


Pertama lihatlah ekstensi Python


Untuk pertama Anda lihat di modul ekstensi Python, Anda perlu untuk kelompok kode ke dalam empat bagian −



- Header file Python.h.


- C fungsi Anda ingin mengekspos sebagai antarmuka dari modul.


- Tabel pemetaan nama-nama fungsi Anda sebagai pengembang Python melihat mereka ke C fungsi dalam modul ekstensi.


- Fungsi inisialisasi.


Header File Python.h

Anda perlu menyertakan Python.h header file di file sumber C, yang memberi Andaakses ke API Python internal yang digunakan untuk menghubungkan modul ke interpreter.

Pastikan untuk menyertakan Python.h sebelum header lain yang mungkin Anda butuhkan. Anda perlu mengikuti termasuk dengan fungsi-fungsi yang ingin Anda panggil dari Python.


C fungsi

Tanda tangan dari C pelaksanaan fungsi Anda selalu mengambil salah satu − tigabentuk berikut




static PyObject *MyFunction( PyObject *self, PyObject *args );

static PyObject *MyFunctionWithKeywords(PyObject *self,
PyObject *args,
PyObject *kw);

static PyObject *MyFunctionWithNoArgs( PyObject *self );

Masing-masing Deklarasi sebelumnya mengembalikan sebuah objek Python. Ada tidak ada hal seperti itu sebagai fungsi Batal dengan Python sebagai ada di C. Jika Anda tidak ingin Anda fungsi untuk mengembalikan nilai, kembali C setara dengan Python tidak ada nilai. Header Python yang mendefinisikan makro, Py_RETURN_NONE, yang artinya ini bagi kita.

Nama-nama fungsi C Anda dapat apa pun yang Anda suka karena mereka tidak pernah terlihat di luar modul ekstensi. Mereka didefinisikan sebagai fungsi statis.

Fungsi C Anda biasanya diberi dengan menggabungkan Python modul dan fungsi nama bersama, seperti yang ditunjukkan di sini −

static PyObject *module_func(PyObject *self, PyObject *args) {
/* Do your stuff here. */
Py_RETURN_NONE;
}
Ini adalah fungsi Python yang disebut func dalam modul modul. Anda akan memasukkan pointer ke fungsi C Anda ke dalam tabel metode untuk modul yang biasanya datang selanjutnya dalam kode sumber.

Tabel pemetaan metode
Tabel metode ini adalah array sederhana struktur PyMethodDef. Struktur tersebutterlihat seperti − ini



struct PyMethodDef {
char *ml_name;
PyCFunction ml_meth;
int ml_flags;
char *ml_doc;
};



Berikut adalah deskripsi anggota struktur ini:

- ml_name: ini adalah nama fungsi sebagai hadiah interpreter Python bila digunakan dalam program Python.

- ml_meth: ini harus alamat ke fungsi yang memiliki salah satu dari tanda tangan dijelaskan dalam seection sebelumnya.

- ml_flags: ini memberitahu penafsir yang ml_meth tiga tanda tangan menggunakan.

  1. Bendera ini biasanya memiliki nilai METH_VARARGS.

 2. Bendera ini dapat bitwise OR'ed dengan METH_KEYWORDS jika Anda ingin membiarkan kunci argumen ke fungsi Anda.

 3. Ini juga dapat memiliki nilai METH_NOARGS yang menunjukkan Anda tidak mau menerima argumen.

- ml_doc: ini adalah docstring untuk fungsi, yang bisa menjadi NULL jika Anda tidak merasa seperti menulis satu.

Tabel ini harus diakhiri dengan sentinel yang terdiri dari nilai-nilai 0 dan NULL bagianggota sesuai.

Contoh
Untuk fungsi yang didefinisikan di atas, kita telah mengikuti metode pemetaan Meja −

static PyMethodDef module_methods[] = {
{ "func", (PyCFunction)module_func, METH_NOARGS, NULL },
{ NULL, NULL, 0, NULL }
};



Fungsi inisialisasi
Bagian terakhir dari modul ekstensi Anda adalah fungsi inisialisasi. Fungsi ini dipanggil oleh Python interpreter ketika modul tersebut dimuat. Hal ini diperlukan bahwa fungsi bernama initModule, di mana modul adalah nama modul.

Fungsi inisialisasi perlu diekspor dari perpustakaan Anda akan membangun. Header Python yang mendefinisikan PyMODINIT_FUNC untuk menyertakan mantra-mantra yang sesuai untuk itu terjadi untuk lingkungan tertentu di mana kita kompilasi. Semua yang harus Anda lakukan adalah menggunakannya ketika menentukan fungsi.

Fungsi inisialisasi C Anda umumnya memiliki berikut keseluruhan struktur −

PyMODINIT_FUNC initModule() {
Py_InitModule3(func, module_methods, "docstring...");
}



Berikut adalah deskripsi Py_InitModule3 fungsi −

func: ini adalah fungsi untuk diekspor.

module_methods: ini adalah tabel pemetaan nama yang didefinisikan di atas.

docstring: ini adalah komentar yang Anda ingin memberikan dalam ekstensi Anda.

Menempatkan ini bersama-sama seperti − berikut

#include <Python.h>

static PyObject *module_func(PyObject *self, PyObject *args) {
/* Do your stuff here. */
Py_RETURN_NONE;
}

static PyMethodDef module_methods[] = {
{ "func", (PyCFunction)module_func, METH_NOARGS, NULL },
{ NULL, NULL, 0, NULL }
};

PyMODINIT_FUNC initModule() {
Py_InitModule3(func, module_methods, "docstring...");
}



Contoh
Sebuah contoh sederhana yang membuat penggunaan semua − konsep-konsep di atas:

#include <Python.h>

static PyObject* helloworld(PyObject* self)
{
return Py_BuildValue("s", "Hello, Python extensions!!");
}

static char helloworld_docs[] =
"helloworld( ): Any message you want to put here!!\n";

static PyMethodDef helloworld_funcs[] = {
{"helloworld", (PyCFunction)helloworld,
METH_NOARGS
, helloworld_docs},
{NULL}
};

void inithelloworld(void)
{
Py_InitModule3("helloworld", helloworld_funcs,
"Extension module example!");
}
Disini fungsi Py_BuildValue digunakan untuk membangun nilai Python. Simpan di atas kode di dalam berkas hello.c. Kita akan melihat bagaimana untuk mengkompilasi dan menginstal modul ini dipanggil dari skrip Python.

Membangun dan menginstal ekstensi:
Paket distutils yang membuatnya sangat mudah untuk mendistribusikan modul Python, murni Python dan ekstensi modul, dengan cara yang standar. Modul didistribusikan dalam bentuk sumber dan dibangun dan diinstal melalui sebuah skrip konfigurasi yang biasanya disebut setup.py sebagai berikut.

Untuk modul di atas, Anda perlu mempersiapkan mengikuti setup.py script −

from distutils.core import setup, Extension
setup
(name='helloworld', version='1.0', \
ext_modules
=[Extension('helloworld', ['hello.c'])])
Sekarang, gunakan perintah berikut, yang akan melakukan semua diperlukan kompilasi dan langkah-langkah yang menghubungkan dengan tepat compiler, linker perintah, dan bendera, dan menyalin perpustakaan dinamis dihasilkan ke direktori yang sesuai −


$ python setup.py install
Pada sistem berbasis Unix, Anda kemungkinan besar akan perlu untuk menjalankan perintah ini sebagai root untuk memiliki izin untuk menulis ke direktori situs-paket. Ini biasanya bukanlah sebuah masalah pada Windows.

Mengimpor ekstensi
Setelah Anda menginstal ekstensi Anda, Anda akan dapat untuk mengimpor dan menghubungi ekstensi itu di skrip Python sebagai berikut −



#!/usr/bin/python
import helloworld

print helloworld.helloworld()
Ini akan menghasilkan − hasil berikut


Hello, Python extensions!!
Melewati parameter fungsi
Seperti Anda akan paling mungkin ingin mendefinisikan fungsi yang menerima argumen, Anda dapat menggunakan salah satu tangan lain untuk fungsi C Anda. Sebagai contoh, fungsi berikut, yang menerima sejumlah parameter, akan ditentukan seperti − ini

static PyObject *module_func(PyObject *self, PyObject *args) {
/* Parse args and do something interesting here. */
Py_RETURN_NONE;
}
Metode tabel berisi entri untuk fungsi baru akan terlihat seperti ini −


static PyMethodDef module_methods[] = {
{ "func", (PyCFunction)module_func, METH_NOARGS, NULL },
{ "func", module_func, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
Anda dapat menggunakan fungsi API PyArg_ParseTuple untuk mengambil argumen dari satu lulus PyObject pointer ke fungsi C Anda.

Argumen pertama untuk PyArg_ParseTuple adalah argumen args. Ini adalah obyek Anda akan parsing. Argumen kedua adalah string format yang menggambarkan argumen seperti yang Anda harapkan mereka untuk tampil. Setiap argumen diwakili oleh satu atau lebih karakter dalam format string sebagai berikut.

static PyObject *module_func(PyObject *self, PyObject *args) {
int i;
double d;
char *s;

if (!PyArg_ParseTuple(args, "ids", &i, &d, &s)) {
return NULL;
}

/* Do something interesting here. */
Py_RETURN_NONE;
}
Menyusun versi baru dari modul dan mengimpor memungkinkan Anda untuk memanggil fungsi baru dengan sejumlah argumen dari setiap jenis −


module.func(1, s="three", d=2.0)
module.func(i=1, d=2.0, s="three")
module.func(s="three", d=2.0, i=1)
Anda mungkin dapat datang dengan lebih variasi.

Fungsi PyArg_ParseTuple
Berikut adalah tanda tangan standar untuk PyArg_ParseTuple fungsi −

int PyArg_ParseTuple(PyObject* tuple,char* format,...)
Fungsi ini mengembalikan 0 untuk kesalahan, dan nilai tidak sama dengan 0 untuk sukses. tupel adalah PyObject * bahwa argumen kedua fungsi C. Format inilah string C yang menggambarkan argumen wajib dan opsional.

Berikut adalah daftar format kode untuk PyArg_ParseTuple fungsi −

CodeC typeMakna
ccharPython string dengan panjang 1 menjadi C char.
ddoublePython pelampung menjadi ganda C.
ffloatPython pelampung menjadi pelampung C.
iintPython int menjadi C int.
llongPython int menjadi C yang panjang.
Llong longPython int menjadi C lama
OPyObject*Mendapat non-NULL referensi meminjam Python argumen.
schar*Python string tanpa tertanam nulls untuk C char *.
s#char*+intSetiap string Python untuk C alamat dan panjang.
t#char*+intHanya-baca satu-segmen penyangga untuk C alamat dan panjang.
uPy_UNICODE*Python Unicode tanpa tertanam nulls c.
u#Py_UNICODE*+intAlamat Python Unicode C dan panjang.
w#char*+intMembaca/menulis satu-segmen penyangga untuk C alamat dan panjang.
zchar*Seperti s, juga tidak mau menerima (set C char * ke NULL).
z#char*+intSeperti s #, juga tidak mau menerima (set C char * ke NULL).
(...)as per ...Urutan Python diperlakukan sebagai salah satu argumen per item.
|Argumen berikut opsional.
:Format akhir, diikuti oleh nama fungsi untuk pesan kesalahan.
;Format akhir, diikuti oleh seluruh kesalahan pesan teks.
Kembali nilai-nilai
Py_BuildValue mengambil dalam format string jauh seperti PyArg_ParseTuple tidak. Bukan lewat di alamat nilai-nilai yang Anda sedang membangun, Anda lulus dalam nilai yang sebenarnya. Berikut adalah contoh bagaimana menerapkan Tambahkan fungsi 

static PyObject *foo_add(PyObject *self, PyObject *args) {
int a;
int b;

if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("i", a + b);
}
Ini adalah apa yang akan terlihat seperti jika dilaksanakan dengan Python −

def add(a, b):
return (a + b)

Anda dapat kembali dua nilai dari fungsi Anda sebagai berikut, ini akan menjadi cauptured yang menggunakan daftar dengan Python.

static PyObject *foo_add_subtract(PyObject *self, PyObject *args) {
int a;
int b;

if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("ii", a + b, a - b);
}

Ini adalah apa yang akan terlihat seperti jika dilaksanakan dengan Python −def add_subtract(a, b):


   return (a + b, a - b)
Py_BuildValue fungsi:

Berikut adalah tanda tangan standar untuk Py_BuildValue fungsi −

PyObject* Py_BuildValue(char* format,...)
Format inilah string C yang menggambarkan objek Python untuk membangun. Argumen berikut Py_BuildValue adalah C nilai yang hasilnya dibangun. PyObject * hasilnya adalah rujukan baru.


Tabel berikut mencantumkan umum digunakan kode string, yang nol atau lebih bergabung ke dalam string format.

CodeC typeMeaning
ccharA C char menjadi Python string of length 1.
ddoubleA C double menjadi Python float.
ffloatA C float menjadi Python float.
iintA C int menjadi Python int.
llongA C panjang menjadi Python int.
NPyObject*Melewati sebuah objek Python dan mencuri referensi.
OPyObject*Melewati sebuah objek Python dan INCREFs itu seperti biasa.
O&convert+void*Sewenang-wenang konversi
schar*C 0-dihentikan char * Python string, atau NULL ke None.
s#char*+intC char * dan panjang ke Python string, atau NULL ke None.
uPy_UNICODE*C-lebar, dihentikan null string Python Unicode, atau NULL ke None.
u#Py_UNICODE*+intString C-lebar dan panjang Python Unicode, atau NULL ke None.
w#char*+intMembaca/menulis satu-segmen penyangga untuk C alamat dan panjang.
zchar*Seperti s, juga tidak mau menerima (set C char * ke NULL).
z#char*+intSeperti s #, juga tidak mau menerima (set C char * ke NULL).
(...)as per ...Membangun Python tupel dari nilai-nilai C.
[...]as per ...Membangun Python daftar dari nilai-nilai C.
{...}as per ...Membangun Python kamus dari nilai-nilai C, bergantian kunci dan nilai.
Kode {...} membangun kamus dari sebuah nomor genap C nilai-nilai, bergantian kunci dan nilai-nilai. Sebagai contoh, Py_BuildValue("{issi}",23,"zig","zag",42) mengembalikan Kamus seperti Python's {23: 'zig', 'zag': 42}.




Subscribe to receive free email updates:

0 Response to "Python ekstensi pemrograman dengan C"

Posting Komentar