рдкрд╛рдпрдерди 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.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:
рдмрдврд╝рд╛рд╡рд╛ рджреЗрдиреЗ рдХреЗ рдкрдХреНрд╖ рдФрд░ рд╡рд┐рдкрдХреНрд╖
рдкреЗрд╢реЗрд╡рд░реЛрдВ :
- рд╕рд░рд▓ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЬрдм рдкрд╛рдпрдерди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рд╡рд┐рдкрдХреНрд╖ :
- рдЖрдкрдХреЛ C ++ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ, рдпрд╛ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рдмрдВрдзрди рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
- рдЕрдХреЗрд▓реЗ рдмрдврд╝рд╛рдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд╣реИ
рдХреЛрдб, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдореИрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЯрд┐рдкреНрдкрдгреА рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рддрд╛ рд╣реВрдВред
1000 рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдкрд░ рдФрд╕рдд рдкрд░реАрдХреНрд╖рдг рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп:
- ctypes: - 0.0004987692832946777 рд╕реЗрдХрдВрдб ---
- CFFI: - 0.00038521790504455566 рд╕реЗрдХрдВрдб ---
- pybind: - 0.0004547207355499268 рд╕реЗрдХрдВрдб ---
- C API: - 0.0003561973571777344 рд╕реЗрдХрдВрдб ---
- рдмрдврд╝рд╛рд╡рд╛: - 0.00037789344787597656 рд╕реЗрдХрдВрдб ---
рд╕рдВрджрд░реНрдн