Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Industrial programming >> Python

Python - Pemrograman Ekstensi dengan C

Halaman SebelumnyaHalaman Berikutnya

Kode apa pun yang Anda tulis menggunakan bahasa yang dikompilasi seperti C, C++, atau Java dapat diintegrasikan atau diimpor ke skrip Python lain. Kode ini dianggap sebagai "ekstensi".

Modul ekstensi Python tidak lebih dari pustaka C normal. Pada mesin Unix, library ini biasanya diakhiri dengan .so (untuk objek bersama). Pada mesin Windows, Anda biasanya melihat .dll (untuk perpustakaan yang ditautkan secara dinamis).

Persyaratan untuk Menulis Ekstensi

Untuk mulai menulis ekstensi, Anda memerlukan file header Python.

Selain itu, diasumsikan bahwa Anda memiliki pengetahuan yang baik tentang C atau C++ untuk menulis Ekstensi Python apa pun menggunakan pemrograman C.

Pertama-tama lihat Ekstensi Python

Untuk tampilan pertama Anda pada modul ekstensi Python, Anda perlu mengelompokkan kode Anda menjadi empat bagian −

File Header Python.h

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

Pastikan untuk menyertakan Python.h sebelum header lain yang mungkin Anda perlukan. Anda harus mengikuti penyertaan dengan fungsi yang ingin Anda panggil dari Python.

Fungsi C

Tanda tangan implementasi C dari fungsi Anda selalu mengambil salah satu dari tiga bentuk berikut −

static PyObject *MyFunction( PyObject *self, PyObject *args );static PyObject *MyFunctionWithKeywords(PyObject *self, PyObject *args, PyObject *kw);static PyObject *gs(self PyObject)WithNobject;

Masing-masing dari deklarasi sebelumnya mengembalikan objek Python. Tidak ada yang namanya kekosongan function di Python seperti yang ada di C. Jika Anda tidak ingin fungsi Anda mengembalikan nilai, kembalikan C setara dengan None Python nilai. Header Python mendefinisikan makro, Py_RETURN_NONE, yang melakukan ini untuk kita.

Nama fungsi C Anda bisa apa saja yang Anda suka karena tidak pernah terlihat di luar modul ekstensi. Mereka didefinisikan sebagai statis fungsi.

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

PyObject statis *module_func (PyObject *self, PyObject *args) { /* Lakukan pekerjaan Anda di sini. */ Py_RETURN_NONE;}

Ini adalah fungsi Python yang disebut fungsi di dalam modul modul . Anda akan meletakkan pointer ke fungsi C Anda ke dalam tabel metode untuk modul yang biasanya muncul berikutnya dalam kode sumber Anda.

Tabel Pemetaan Metode

Tabel metode ini adalah array sederhana dari struktur PyMethodDef. Struktur itu terlihat seperti ini

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

Berikut adalah deskripsi anggota struktur ini

Tabel ini perlu diakhiri dengan sentinel yang terdiri dari nilai NULL dan 0 untuk anggota yang sesuai.

Contoh

Untuk fungsi yang didefinisikan di atas, kami memiliki tabel pemetaan metode berikut

modul PyMethodDef statis _metode[] ={ { "fungsi ", (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 interpreter Python ketika modul dimuat. Fungsi tersebut harus diberi nama initModul , di mana Modul adalah nama modul.

Fungsi inisialisasi perlu diekspor dari perpustakaan yang akan Anda bangun. Header Python mendefinisikan PyMODINIT_FUNC untuk menyertakan mantra yang sesuai agar hal itu terjadi untuk lingkungan tertentu tempat kami mengompilasi. Yang harus Anda lakukan adalah menggunakannya saat mendefinisikan fungsi.

Fungsi inisialisasi C Anda umumnya memiliki struktur keseluruhan berikut

PyMODINIT_FUNC initModul () { Py_InitModule3(fungsi , modul _methods, "docstring...");}

Berikut adalah deskripsi Py_InitModule3 fungsi

Menyatukan ini semua terlihat seperti berikut −

#include PyObject statis *module_func (PyObject *self, PyObject *args) { /* Lakukan pekerjaan Anda di sini. */ Py_RETURN_NONE;}modul PyMethodDef statis _metode[] ={ { "fungsi ", (PyCFunction)module_func , METH_NOARGS, NULL }, { NULL, NULL, 0, NULL }};PyMODINIT_FUNC initModul () { Py_InitModule3(fungsi , modul _methods, "docstring...");}

Contoh

Contoh sederhana yang menggunakan semua konsep di atas

#include static PyObject* helloworld(PyObject* self) { return Py_BuildValue("s", "Halo, ekstensi Python!!");}static char helloworld_docs[] ="helloworld( ):Pesan apa pun yang ingin Anda taruh di sini!!\n";static PyMethodDef helloworld_funcs[] ={ {"helloworld", (PyCFunction)helloworld, METH_NOARGS, helloworld_docs}, {NULL}};void inithelloworld(void) { Py_InitModule3("helloworld", helloworld_funcs, "Contoh modul ekstensi!");}

Ini Py_BuildValue fungsi digunakan untuk membangun nilai Python. Simpan kode di atas dalam file hello.c. Kita akan melihat bagaimana mengkompilasi dan menginstal modul ini untuk dipanggil dari skrip Python.

Membuat dan Memasang Ekstensi

Distutil package membuatnya sangat mudah untuk mendistribusikan modul Python, baik Python murni maupun modul ekstensi, dengan cara standar. Modul didistribusikan dalam bentuk sumber dan dibuat serta diinstal melalui skrip penyiapan yang biasanya disebut setup.py sebagai berikut.

Untuk modul di atas, Anda perlu menyiapkan skrip setup.py berikut

dari distutils.core import setup, Extensionsetup(name='helloworld', version='1.0', \ ext_modules=[Extension('helloworld', ['hello.c'])]) 

Sekarang, gunakan perintah berikut, yang akan melakukan semua langkah kompilasi dan penautan yang diperlukan, dengan perintah dan flag compiler dan linker yang tepat, dan menyalin pustaka dinamis yang dihasilkan ke direktori yang sesuai −

$ python setup.py install

Pada sistem berbasis Unix, kemungkinan besar Anda harus menjalankan perintah ini sebagai root agar memiliki izin untuk menulis ke direktori paket situs. Ini biasanya bukan masalah di Windows.

Mengimpor Ekstensi

Setelah Anda menginstal ekstensi Anda, Anda akan dapat mengimpor dan memanggil ekstensi itu dalam skrip Python Anda sebagai berikut −

#!/usr/bin/pythonimport helloworldprint helloworld.helloworld()

Ini akan menghasilkan hasil berikut

Halo, ekstensi Python!!

Meneruskan Parameter Fungsi

Karena kemungkinan besar Anda ingin mendefinisikan fungsi yang menerima argumen, Anda dapat menggunakan salah satu tanda tangan lain untuk fungsi C Anda. Misalnya, fungsi berikut, yang menerima sejumlah parameter, akan didefinisikan seperti ini

PyObject statis *module_func (PyObject *self, PyObject *args) { /* Parsing args dan lakukan sesuatu yang menarik di sini. */ Py_RETURN_NONE;}

Tabel metode yang berisi entri untuk fungsi baru akan terlihat seperti ini

modul PyMethodDef statis _metode[] ={ { "fungsi ", (PyCFunction)module_func , METH_NOARGS, NULL }, { "fungsi ", modul_fungsi , METH_VARARGS, NULL }, { NULL, NULL, 0, NULL }};

Anda dapat menggunakan API PyArg_ParseTuple fungsi untuk mengekstrak argumen dari satu pointer PyObject yang diteruskan ke fungsi C Anda.

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

PyObject statis *module_func (PyObject *self, PyObject *args) { int i; ganda d; karakter *s; if (!PyArg_ParseTuple(args, "id", &i, &d, &s)) { kembali NULL; } /* Lakukan sesuatu yang menarik di sini. */ Py_RETURN_NONE;}

Mengkompilasi versi baru modul Anda dan mengimpornya memungkinkan Anda untuk memanggil fungsi baru dengan sejumlah argumen jenis apa pun −

module.func(1, s="three", d=2.0)module.func(i=1, d=2.0, s="three")module.func(s=" tiga", d=2.0, i=1)

Anda mungkin bisa membuat lebih banyak variasi.

PyArg_ParseTuple Fungsi

Berikut adalah tanda tangan standar untuk PyArg_ParseTuple fungsi

int PyArg_ParseTuple(PyObject* tuple,char* format,...)

Fungsi ini mengembalikan 0 untuk kesalahan, dan nilai yang tidak sama dengan 0 untuk keberhasilan. tuple adalah PyObject* yang merupakan argumen kedua fungsi C. Berikut format adalah string C yang menjelaskan argumen wajib dan opsional.

Berikut adalah daftar kode format untuk PyArg_ParseTuple fungsi

Kode Tipe C Arti
c char String Python dengan panjang 1 menjadi karakter C.
d ganda Float Python menjadi double C.
f mengambang Apungan Python menjadi pelampung C.
i int Int Python menjadi int C.
l panjang Int Python menjadi panjang C.
L panjang panjang Int Python menjadi panjang C
O PyObject* Mendapatkan referensi pinjaman non-NULL untuk argumen Python.
s char* String python tanpa null yang disematkan ke C char*.
s# char*+int Semua string Python ke alamat dan panjang C.
t# char*+int Buffer segmen tunggal read-only ke alamat dan panjang C.
u Py_UNICODE* Python Unicode tanpa menyematkan null ke C.
u# Py_UNICODE*+int Alamat dan panjang Python Unicode C apa saja.
w# char*+int Baca/tulis buffer segmen tunggal ke alamat dan panjang C.
z char* Seperti s, juga menerima None (menyetel C char* ke NULL).
z# char*+int Seperti s#, juga menerima None (menyetel C char* ke NULL).
(...) sesuai ... Urutan Python diperlakukan sebagai satu argumen per item.
Argumen berikut ini opsional.
Format akhir, diikuti dengan nama fungsi untuk pesan kesalahan.
Format akhir, diikuti oleh seluruh teks pesan kesalahan.

Mengembalikan Nilai

Py_BuildValue mengambil format string seperti PyArg_ParseTuple melakukan. Alih-alih meneruskan alamat nilai yang Anda buat, Anda meneruskan nilai sebenarnya. Berikut adalah contoh yang menunjukkan cara menerapkan fungsi tambah −

static PyObject *foo_add(PyObject *self, PyObject *args) { int a; int b; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { kembali NULL; } mengembalikan Py_BuildValue("i", a + b);}

Beginilah jadinya jika diimplementasikan dengan Python

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

Anda dapat mengembalikan dua nilai dari fungsi Anda sebagai berikut, ini akan ditangkap menggunakan daftar dengan Python.

static PyObject *foo_add_subtract(PyObject *self, PyObject *args) { int a; int b; if (!PyArg_ParseTuple(args, "ii", &a, &b)) { kembali NULL; } mengembalikan Py_BuildValue("ii", a + b, a - b);}

Beginilah jadinya jika diimplementasikan 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,...)

Berikut format adalah string C yang menjelaskan objek Python yang akan dibangun. Argumen berikut dari Py_BuildValue adalah nilai C dari mana hasilnya dibangun. PyObject* hasilnya adalah referensi baru.

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

Kode Tipe C Arti
c char A C char menjadi string Python dengan panjang 1.
d ganda A C double menjadi float Python.
f mengambang Apungan C menjadi pelampung Python.
i int Int C menjadi int Python.
l panjang Panjang C menjadi int Python.
T PyObject* Meneruskan objek Python dan mencuri referensi.
O PyObject* Meneruskan objek Python dan memasukkannya seperti biasa.
O& convert+void* Konversi sewenang-wenang
s char* C 0-dihentikan char* ke string Python, atau NULL ke None.
s# char*+int C char* dan panjangnya ke string Python, atau NULL ke None.
u Py_UNICODE* C-wide, string diakhiri null ke Python Unicode, atau NULL ke None.
u# Py_UNICODE*+int String lebar-C dan panjang ke Python Unicode, atau NULL ke None.
w# char*+int Baca/tulis buffer segmen tunggal ke alamat dan panjang C.
z char* Seperti s, juga menerima None (menyetel C char* ke NULL).
z# char*+int Seperti s#, juga menerima None (menyetel C char* ke NULL).
(...) sesuai ... Membangun tupel Python dari nilai C.
[...] sesuai ... Membuat daftar Python dari nilai C.
{...} sesuai ... Membangun kamus Python dari nilai C, kunci dan nilai bergantian.

Kode {...} membangun kamus dari jumlah nilai C yang genap, secara bergantian kunci dan nilai. Misalnya, Py_BuildValue("{issi}",23,"zig","zag",42) mengembalikan kamus seperti {23:'zig','zag':42} Python.


Python

  1. Python List Comprehension, Append, Sort, Length [CONTOH]
  2. Python dengan Konektivitas MySQL:Konektor, Buat Database, Tabel, Sisipkan [Contoh]
  3. Bagaimana cara mendapatkan tanggal dan waktu saat ini dengan Python?
  4. Python - Pengambilan Keputusan
  5. Warisan Python
  6. Pernyataan lulus Python