рд╣рдо рдкрд╛рдпрдерди 3 рд╕реЗ C / C ++ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЗ рд╡рд┐рд╖рдп рдХреЛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ ред рдЕрдм рд╣рдо cffi , pybind11 рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ ред рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ ctypes рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд┐рдзрд┐ рдкрд░ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рдереАред
рд╕реА
рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░, рд╕рдВрд░рдЪрдирд╛рдУрдВ рдФрд░ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реАрдХреНрд╖рдг рдкреБрд╕реНрддрдХрд╛рд▓рдпред
test.h
typedef struct test_st_s test_st_t; extern int a; extern double b; extern char c; 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); test_st_t *func_ret_struct(test_st_t *test_st); struct test_st_s { int val1; double val2; char val3; };
test.c
#include <stdio.h> #include <stdlib.h> #include "test.h" 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; } char * func_ret_str(char *val) { printf("C get func_ret_str: %s\n", val); return 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; }
рдкреБрд╕реНрддрдХрд╛рд▓рдп рдмрд┐рд▓реНрдХреБрд▓ рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕рд╛ рдХрд┐ ctypes рд▓реЗрдЦ рдореЗрдВ рд╣реИред
CFFI
рдпрд╣ рд╕реА рдХреЗ рд╕рд╛рде рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ ред рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд╡рд┐рд╡рд░рдг рд╕реЗ:
рдкрд╛рдпрдерди рд╕реЗ рд▓рдЧрднрдЧ рдХрд┐рд╕реА рднреА рд╕реА рдХреЛрдб рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд
рдЗрд╕рдореЗрдВ рд╕реЗ рдХреБрдЫ рд▓рдЧрднрдЧ рдкрд╛рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рд╕рдВрд╕реНрдХрд░рдг 1.12.3 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ , рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╣рд╛рдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред
2 рд╢рдмреНрджреЛрдВ рдореЗрдВ рдЗрд╕ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдереЛрдбрд╝рд╛, рд╕реАрдПрдлрдПрдлрдЖрдИ рд╣рдорд╛рд░реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рдЕрдкрдиреЗ рдмрдВрдзрди рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдо рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред
рд╕реНрдерд╛рдкрдирд╛
pip3 рд╕реНрдерд╛рдкрд┐рдд cffi
рд╕рднрд╛
рдмрд┐рд▓реНрдб рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬреЛ рд╣рдорд╛рд░реЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдПрдХрддреНрд░ рдХрд░реЗрдЧреАред
build.py
import os import cffi if __name__ == "__main__": ffi = cffi.FFI()
рдЕрдЬрдЧрд░
рд╕реАрдПрдлрдЖрдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рдпрдерди рд╕реЗ рд╕реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
from cffi import FFI import sys import time
C ++ рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЗрд╕рдХреЗ рд▓рд┐рдП C рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛ред Ctypes рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд┐рдзрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд░рдирд╛ рд╣реИред рдиреАрдЪреЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВред
рд╕реАрдПрдлрдПрдлрдЖрдИ рдХреЗ рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖
рдкреЗрд╢реЗрд╡рд░реЛрдВ :
- рд╕рд░рд▓ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЬрдм рдкрд╛рдпрдерди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
- рд╕реНрд░реЛрдд рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓рдиреЗ рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ
рд╡рд┐рдкрдХреНрд╖ :
pybind11
pybind11, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ C ++ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред рд╕рдВрд╕реНрдХрд░рдг 2.3.0 рдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ , рдЖрдк рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдпрд╣рд╛рдВ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд╣ рд╕реА рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рд╕реА ++ рд╕реНрд░реЛрддреЛрдВ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд┐рдпрд╛ред
рд╕реНрдерд╛рдкрдирд╛
pip3 рд╕реНрдерд╛рдкрд┐рдд pybind11
рд╕рднрд╛
рд╣рдореЗрдВ рдЕрдкрдиреА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд▓рд┐рдЦрдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИред
build.py
import pybind11 from distutils.core import setup, Extension ext_modules = [ Extension( '_test',
рд╣рдо рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:
python3 setup.py build --build-lib=./lib
рд╕реА ++
рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕реНрд░реЛрдд рдореЗрдВ рдЖрдкрдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:
namespace py = pybind11;
рдЕрдЬрдЧрд░
Pybind11 рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╛рдпрдерди рд╕реЗ C рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг:
import sys import time
Pybind11 рдХреЗ рдкреЗрд╢реЗрд╡рд░реЛрдВ рдФрд░ рд╡рд┐рдкрдХреНрд╖
рдкреЗрд╢реЗрд╡рд░реЛрдВ :
- рд╕рд░рд▓ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдЬрдм рдкрд╛рдпрдерди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рд╡рд┐рдкрдХреНрд╖ :
- рдЖрдкрдХреЛ C ++ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рд╕рдВрдкрд╛рджрд┐рдд рдХрд░рдиреЗ, рдпрд╛ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рдмрдВрдзрди рд▓рд┐рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ
- рд╕реНрд░реЛрдд рд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдПрдХрддреНрд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ
1000 рдХреЗ рд╕рд╛рде рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдзрд┐ рдкрд░ рдФрд╕рдд рдкрд░реАрдХреНрд╖рдг рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп:
- ctypes: - 0.0004987692832946777 рд╕реЗрдХрдВрдб ---
- CFFI: - 0.00038521790504455566 рд╕реЗрдХрдВрдб ---
- pybind: - 0.0004547207355499268 рд╕реЗрдХрдВрдб ---
+, - рдХреНрдпреЛрдВрдХрд┐ рд╣рд░ рдмрд╛рд░ рдкрд░рд┐рдгрд╛рдо рдереЛрдбрд╝реЗ рдЕрд▓рдЧ рдереЗред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рдордп рдореБрджреНрд░рдг рдореЗрдВ рдЦрд░реНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕реЗ рдмрдВрдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВ рдмрд╣реБрдд рдЖрд▓рд╕реА рдерд╛ (рдЗрд╕ рд╕рдордп рдХреЛ рдПрдХ рд╕реНрдерд┐рд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдВ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рд╕рднреА рдкрд░реАрдХреНрд╖рдгреЛрдВ рдореЗрдВ ~ рдПрдХ рд╣реА рд╣реЛрдЧрд╛)ред рд▓реЗрдХрд┐рди рдлрд┐рд░ рднреА, рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдФрд░ рдЙрдирд╕реЗ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдордп рдЕрдВрддрд░ рд╣реИред
рд╕рдВрджрд░реНрдн