рдкрд╛рдпрдерди (рдмрдврд╝рд╛рд╡рд╛) рд╕реЗ рд╕реА / рд╕реА ++

рдореБрдЦреНрдп

рдкрд╛рдпрдерди 3 рд╕реЗ рд╕реА / рд╕реА ++ рдХреЛ рдХреИрд╕реЗ рдЖрдордВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдП, рдЗрд╕ рдкрд░ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рдЕрдВрддрд┐рдо рд▓реЗрдЦ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд╕рднреА рдЬреНрдЮрд╛рдд рддрд░реАрдХреЛрдВ рд╕реЗ рдЧреБрдЬрд░рд╛ ред рдЗрд╕ рдмрд╛рд░ рдореБрдЭреЗ рдмрдврд╝рд╛рд╡рд╛ рдорд┐рд▓рд╛ред рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдиреАрдЪреЗ рдХреНрдпрд╛ рдкрдврд╝рд╛ рдЧрдпрд╛


рд╕реА


рдореИрдВ рдПрдХ рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдПрдХ рд╣реА рдЙрджрд╛рд╣рд░рдг рд▓реЗрддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рднрд┐рдиреНрдирддрд╛ рдмрдирд╛рддрд╛ рд╣реВрдВред рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░, рд╕рдВрд░рдЪрдирд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкреБрд╕реНрддрдХрд╛рд▓рдпред


test.c:


#include "test.hpp" int a = 5; double b = 5.12345; char c = 'X'; int func_ret_int(int val) { printf("C get func_ret_int: %d\n", val); return val; } double func_ret_double(double val) { printf("C get func_ret_double: %f\n", val); return val; } object func_ret_str(char *val) { printf("C get func_ret_str: %s\n", val); return object(string(val)); } char func_many_args(int val1, double val2, char val3, short val4) { printf("C get func_many_args: int - %d, double - %f, char - %c, short - %d\n", val1, val2, val3, val4); return val3; } 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; } // _test    BOOST_PYTHON_MODULE(_test) { /* *   */ def("func_ret_int", func_ret_int); def("func_ret_double", func_ret_double); def("func_ret_str", &func_ret_str); def("func_many_args", func_many_args); //   // manage_new_object C     // reference_existing_object C     def("func_ret_struct", &func_ret_struct, return_value_policy<reference_existing_object>()); /* *    */ scope().attr("a") = a; scope().attr("b") = b; scope().attr("c") = c; /* *  */ class_<test_st_t>("test_st_t") .def_readwrite("val1", &test_st_t::val1) .def_readwrite("val2", &test_st_t::val2) .def_readwrite("val3", &test_st_t::val3) ; } 

test.h:


 using namespace boost::python; using namespace std; #ifdef __cplusplus extern "C" { #endif typedef struct test_st_s test_st_t; typedef char * char_p; extern int a; extern double b; extern char c; int func_ret_int(int val); double func_ret_double(double val); object func_ret_str(char *val); char func_many_args(int val1, double val2, char val3, short val4); test_st_t *func_ret_struct(test_st_t *test_st); struct test_st_s { int val1; double val2; char val3; }; #ifdef __cplusplus } #endif 

рдХреИрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ:


 g++ -g -fPIC -I/usr/include/python3.6 -I./src/c -o ./objs/test.o -c ./src/c/test.cpp g++ -fPIC -g -shared -o ./lib/_test.so ./objs/test.o -lboost_python3 

рд╕реНрд░реЛрдд рдПрдХ рдЧрддрд┐рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред
рдЕрдЬрдЧрд░ рдХреА рд╡реГрджреНрдзрд┐ pybind11 рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдЖрдкрдХреЛ рдЙрди рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рднреА рд╡рд░реНрдгрди рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬреЛ рдЕрдЬрдЧрд░ рджреЗрдЦреЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдмрдврд╝рд╛рд╡рд╛ рдЕрдзрд┐рдХ рднрд╛рд░реА рдФрд░ рдЬрдЯрд┐рд▓ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:


 def("func_ret_struct", &func_ret_struct, return_value_policy<reference_existing_object>()); 

Func_ret_struct рдлрд╝рдВрдХреНрд╢рди рдПрдХ рд╕рдВрдХреЗрддрдХ рдХреЛ рдПрдХ рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЙрд╕реА рд╕реВрдЪрдХ рдХреЛ рд╡рд╛рдкрд╕ рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд▓реМрдЯреА рд╣реБрдИ рд╡рд╕реНрддреБ return_value_policy <reference_existing_object> () рдХреЗ рдирд┐рдпрдореЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред reference_existing_objec рдХрд╛ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ рд▓реМрдЯреА рд╣реБрдИ рд╡рд╕реНрддреБ рдкрд╣рд▓реЗ рд╕реЗ рдореМрдЬреВрдж рд╣реИред рдпрджрд┐ рдЖрдк manage_new_object рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдо рдПрдХ рдирдИ рд╡рд╕реНрддреБ рд▓реМрдЯрд╛ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕ рддрд░рд╣ рдХреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдХрд░реНрддрд╛ рдкрд░ рдПрдХ рд╡рд┐рднрд╛рдЬрди рджреЛрд╖ рдореЗрдВ рдЖ рдЬрд╛рдПрдЧреА:


 test_st = _test.test_st_t() ret = _test.func_ret_struct(test_st) 

рдХреНрдпреЛрдВрдХрд┐ рдХрдЪрд░рд╛ рд╕рдВрдЧреНрд░рд╣рдХрд░реНрддрд╛ рдкрд╣рд▓реЗ рдЙрд╕ рдбреЗрдЯрд╛ рдХреЛ рд╕рд╛рдлрд╝ рдХрд░ рджреЗрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ test_st рд╕рдореНтАНрдорд┐рд▓рд┐рдд рд╣реИ, рдФрд░ рдлрд┐рд░ рд╡рд╣ рдбреЗрдЯрд╛ рд╕рд╛рдлрд╝ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд░реЗрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рд╢рд╛рдорд┐рд▓ рд╣реИред рдЬрд┐рд╕рдореЗрдВ рд╡рд╣реА рдбреЗрдЯрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ test_st рдореЗрдВ рд╕рдорд╛рд╣рд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдкрд╣рд▓реЗ рд╣реА рд╕рд╛рдлрд╝ рд╣реЛ рдЪреБрдХрд╛ рд╣реИред


рдпрд╣ рджрд┐рд▓рдЪрд╕реНрдк рд╣реИ рдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд╡рд░реНрдгрди рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЧрдпрд╛ (рдЧрд╣рд░рд╛ рдирд╣реАрдВ рдЧрдпрд╛) ?:


 test_st_t * func_ret_struct(test_st_t *test_st) { if (test_st) { return test_st; } else { return (test_st_t *) malloc(sizeof(test_st_t)); } } 

рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рдХрд┐рд╕реА рдореМрдЬреВрджрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдПрдХ рдореМрдЬреВрджрд╛ рднреА рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддрд╛ рд╣реИред


рдореБрдЭреЗ рдЗрд╕ рддрд░рд╣ рдХреЗ рд╕рдорд╛рд░реЛрд╣ рдореЗрдВ рднреА рд╕рдорд╕реНрдпрд╛ рдереА:


 char * func_ret_str(char *val) { return val; } 

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдЖрдк рдХреЛ рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдореЗрдВ рдЕрдЬрдЧрд░ рд╕реЗ рдорд╛рдирдХ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреЗрддрдХ рдирд╣реАрдВ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдХреЗрд╡рд▓ рд╕рдВрд░рдЪрдирд╛ , рд╡рд░реНрдЧ рдФрд░ рд╕рдВрдШ рдкрд░ рд╣реА рд╕рдВрднрд╡ рд╣реИред рдЕрдЧрд░ рдХрд┐рд╕реА рдХреЛ рдЖрддреНрдордЬреНрдЮрд╛рди рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдкрддрд╛ рд╣реИред


рдЕрдЬрдЧрд░


рдЕрдЬрдЧрд░ рдХреЗ рд▓рд┐рдП, рдореЙрдбреНрдпреВрд▓ рджреЗрд╢реА рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
main.py:


 #!/usr/bin/python3 #-*- coding: utf-8 -*- import sys import time #    test #sys.path.append('.') sys.path.append('lib/') #   import _test ### ## C ### print("boost\n") print("C\n") start_time = time.time() ## #    ## print('  :') print('ret func_ret_int: ', _test.func_ret_int(101)) print('ret func_ret_double: ', _test.func_ret_double(12.123456789)) print('ret func_ret_str: ', _test.func_ret_str('Hello!')) print('ret func_many_args: ', _test.func_many_args(15, 18.1617, 'X', 32000)) ## #    ## print('\n  :') print('ret a: ', _test.a) #   . _test.a = 22 print('new a: ', _test.a) print('ret b: ', _test.b) print('ret c: ', _test.c) ## #    ## print('\n  :') #      test_st = _test.test_st_t() test_st.val1 = 5 test_st.val2 = 5.1234567 test_st.val3 = 'Z' print('val1 = {}\nval2 = {}\nval3 = {}'.format(test_st.val1, test_st.val2, test_st.val3)) ret = _test.func_ret_struct(test_st) #    C print('ret val1 = {}\nret val2 = {}\nret val3 = {}'.format(ret.val1, ret.val2, ret.val3)) #   print("--- {} seconds ---".format(time.time() - start_time)) 

рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рдкрдХреНрд╖ рдФрд░ рд╡рд┐рдкрдХреНрд╖


рдкреЗрд╢реЗрд╡рд░реЛрдВ :


  • рд╕рд░рд▓ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЬрдм рдкрд╛рдпрдерди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

рд╡рд┐рдкрдХреНрд╖ :


  • рдЖрдкрдХреЛ C ++ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ, рдпрд╛ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рдмрдВрдзрди рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
  • рдЕрдХреЗрд▓реЗ рдмрдврд╝рд╛рдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ

рдХреЛрдб, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдореИрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реВрдВред


1000 рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдкрд░ рдФрд╕рдд рдкрд░реАрдХреНрд╖рдг рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп:


  • ctypes: - 0.0004987692832946777 рд╕реЗрдХрдВрдб ---
  • CFFI: - 0.00038521790504455566 рд╕реЗрдХрдВрдб ---
  • pybind: - 0.0004547207355499268 рд╕реЗрдХрдВрдб ---
  • C API: - 0.0003561973571777344 рд╕реЗрдХрдВрдб ---
  • рдмрдврд╝рд╛рд╡рд╛: - 0.00037789344787597656 рд╕реЗрдХрдВрдб ---

рд╕рдВрджрд░реНрдн


Source: https://habr.com/ru/post/hi471618/


All Articles