Saya menulis tentang cara memanggil Python dari C di artikel sebelumnya, sekarang kita akan berbicara tentang bagaimana melakukan yang sebaliknya dan memanggil C / C ++ dari Python3 . Begitu saya mulai menulis tentang ini, kami akan mengungkapkan seluruh topik sampai akhir. Selain itu, tidak ada yang rumit di sini.
C
Semuanya sederhana di sini, Python dapat memanggil fungsi C tanpa masalah.
test.c:
#include "test.h" int a = 5; double b = 5.12345; char c = 'X'; int func_ret_int(int val) { printf("get func_ret_int: %d\n", val); return val; } double func_ret_double(double val) { printf("get func_ret_double: %f\n", val); return val; } char * func_ret_str(char *val) { printf("get func_ret_str: %s\n", val); return val; } char func_many_args(int val1, double val2, char val3, short val4) { printf("get func_many_args: int - %d, double - %f, char - %c, short - %d\n", val1, val2, val3, val4); return val3; }
test.h:
#ifndef _TEST_H_ #define _TEST_H_ #ifdef __cplusplus extern "C" { #endif #include <stdio.h> #include <string.h> #include <unistd.h> int func_ret_int(int val); double func_ret_double(double val); char *func_ret_str(char *val); char func_many_args(int val1, double val2, char val3, short val4) #ifdef __cplusplus } #endif #endif /* _TEST_H_ */
Cara mengompilasi:
gcc -fPIC -shared -o libtest.so test.c
Sumber dikompilasi ke dalam perpustakaan yang dinamis dan siap untuk pertempuran.
Kami beralih ke Python. Contoh ini menunjukkan cara meneruskan argumen ke suatu fungsi, mendapatkan hasil dari suatu fungsi, dan bagaimana mendapatkan dan mengubah nilai-nilai variabel global.
main.py:
Semua tipe data yang mungkin dan peruntukannya dapat ditemukan dalam dokumentasi Python.
Bekerja dengan struktur
Deklarasi struktur C dalam test.h:
typedef struct test_st_s test_st_t; struct test_st_s { int val1; double val2; char val3; };
Fungsi untuk bekerja dengan struktur kami:
test_st_t * func_ret_struct(test_st_t *test_st) { if (test_st) { printf("C get test_st: val1 - %d, val2 - %f, val3 - %c\n", test_st->val1, test_st->val2, test_st->val3); } return test_st; }
Python:
import sys import struct
C ++
Ini sedikit lebih rumit di sini, karena ctypes hanya dapat bekerja dengan fungsi C. Ini bukan masalah bagi kami, hanya C yang mengikat kode C ++.
Metode kelas C ++ dan binding C:
#include "test.hpp" std::string test::ret_str(std::string val) { std::cout << "get ret_str: " << val << std::endl; return val; } int test::ret_int(int val) { std::cout << "get ret_int: " << val << std::endl; return val; } double test::ret_double(double val) { std::cout << "get ret_double: " << val << std::endl; return val; } /* * C C++ */ // test, . test *test_new() { return new test(); } // test. void test_del(test *test) { delete test; } /* * . */ // ret_str char *test_ret_str(test *test, char *val) { // char * std::string std::string str = test->ret_str(std::string(val)); // std::string char * char *ret = new char[str.length() + 1]; strcpy(ret, str.c_str()); return ret; } // ret_int int test_ret_int(test *test, int val) { return test->ret_int(val); } // ret_double double test_ret_double(test *test, double val) { return test->ret_double(val); } /* * . */ // a int test_get_a(test *test) { return test->a; } // b double test_get_b(test *test) { return test->b; } // c char test_get_c(test *test) { return test->c; }
Tetapi ada satu peringatan, pengikatan harus dinyatakan sebagai eksternal C. Sehingga kompilator ++ tidak membebani nama fungsi yang mengikat. Jika ya, maka kita tidak akan dapat bekerja dengan fungsi kita melalui ctypes.
test.hpp:
#include <iostream> #include <string.h> class test { public: int a = 5; double b = 5.12345; char c = 'X'; std::string ret_str(std::string val); int ret_int(int val); double ret_double(double val); }; #ifdef __cplusplus extern "C" { #endif test *test_new(); void test_del(test *test); char *test_ret_str(test *test, char *val); int test_ret_int(test *test, int val); double test_ret_double(test *test, double val); int test_get_a(test *test); double test_get_b(test *test); char test_get_c(test *test); #ifdef __cplusplus } #endif
Cara mengompilasi:
g ++ -fPIC-shared -o libtestpp.so test.cpp
Python sama mudahnya.
Pro dan kontra dari ctypes
Pro :
- Anda dapat menghubungkan perpustakaan C yang sudah dikompilasi
Cons :
- Dalam Python, Anda perlu menjelaskan fungsi C yang kembali dan diterima sebagai argumen.
Kode mencoba mengomentari dengan jelas, untuk menulis lebih sedikit di sini)
Semoga bermanfaat.
Terima kasih
DollaR84 atas bantuannya.
Palich239 untuk kesalahan yang ditemukan.
Referensi