ูƒูŠู ุชุตู†ุน ุจูŠุซูˆู† ุบู„ุงู ูˆู„ุง ุชุบุถุจ

ู„ู‚ุฏ ู‚ุฑุฃุช ู…ุคุฎุฑู‹ุง ู…ู‚ุงู„ู‹ุง ุนู† ู‡ุงุจุฑูŠ ุญูˆู„ ุฃุฏุงุฉ ู…ููŠุฏุฉ ู„ู„ุบุงูŠุฉ ุŒ ูˆุจู…ุง ุฃู†ู†ูŠ ูƒู†ุช ุฃุจุญุซ ุนู† ู†ูˆุน ู…ู† ุงู„ู…ุดุฑูˆุน ู„ูุชุฑุฉ ุทูˆูŠู„ุฉ ู„ุจุฏุก ุงู„ู…ุณุงู‡ู…ุฉ ุŒ ูู‚ุฏ ู‚ุฑุฑุช ุฃู† ุฃุฑู‰ ู…ุง ู‡ูˆ ุนู„ู‰ ุฌูŠุซุจ ูˆูƒูŠู ูŠู…ูƒู†ู†ูŠ ุงู„ู…ุณุงุนุฏุฉ. ูƒุงู†ุช ู‡ู†ุงูƒ ู…ุดูƒู„ุฉ ูˆุงุญุฏุฉ ุญูˆู„ ุฅู†ุดุงุก ู…ุฌู…ู‘ุน (ุณุฃุณุชุฎุฏู… ุงู„ู…ุฌู…ุน ู„ุงุญู‚ู‹ุง) ู„ู„ู…ูƒุชุจุฉ C. ููŠ ุชู„ูƒ ุงู„ู„ุญุธุฉ ุงุนุชู‚ุฏุช ุŒ "ุฃูˆู‡ ุŒ ุดูŠุก ู…ุซูŠุฑ ู„ู„ุงู‡ุชู…ุงู… ุŒ ุฃู†ุง ู…ุชุฃูƒุฏ ู…ู† ุฃู† ุงู„ุฃู…ุฑ ู„ู† ูŠุณุชุบุฑู‚ ุฃูƒุซุฑ ู…ู† ุณุงุนุฉ." ูƒู… ูƒู†ุช ู…ุฎุทุฆุง.


ููŠ ู‡ุฐู‡ ุงู„ู…ู‚ุงู„ุฉ ุŒ ู‚ุฑุฑุช ุนุฏู… ุฅุธู‡ุงุฑ ุทุฑูŠู‚ุฉ ูˆุงุญุฏุฉ ู„ุญู„ ู…ุดูƒู„ุฉ ู…ู…ุงุซู„ุฉ ุŒ ูˆู„ูƒู† ุนุฏุฉ ุฎูŠุงุฑุงุช ู…ุฎุชู„ูุฉ. ุณุฃุนุฑุถ ู„ูƒ ุฎูŠุงุฑุงุช ู„ุฅู†ุดุงุก ูˆุญุฏุงุช ููŠ Python ู…ุน ุชุฑุฌู…ุฉ ููŠ C ุŒ ุจุงุณุชุฎุฏุงู… ู…ูƒุชุจุฉ ุตุบูŠุฑุฉ ู…ูƒุชูˆุจุฉ ุฐุงุชูŠู‹ุง C ููŠ Python ุŒ ูˆ- ุงู„ุฎูŠุงุฑ ุงู„ุฃุฎูŠุฑ - ุจุงุณุชุฎุฏุงู… ู…ูƒุชุจุฉ C ูƒุจูŠุฑุฉ ููŠ Python ุจุฏูˆู† ุฃู„ู… ูˆู…ู„ูุงุช pxd.


Cython


ุชู…ุช ูƒุชุงุจุฉ ุงู„ูƒุชุจ ุจุงู„ูุนู„ ุญูˆู„ ู‡ุฐุง ุงู„ู…ูˆุถูˆุน ุŒ ูู‡ู†ุงูƒ ุงู„ุนุฏูŠุฏ ู…ู† ุงู„ู…ู‚ุงู„ุงุช ุŒ ุจู…ุง ููŠ ุฐู„ูƒ ุญูˆู„ Habrรฉ ุŒ ู„ุฐู„ูƒ ู„ู† ุฃุฑูƒุฒ ูƒุซูŠุฑู‹ุง ุนู„ู‰ ุงู„ุชุซุจูŠุช ุฃูˆ ุจุนุถ ุงู„ุฃุดูŠุงุก ุงู„ุฃุณุงุณูŠุฉ. ุงู‚ุฑุฃ ุงู„ู…ุฒูŠุฏ ู‡ู†ุง


ุจุงุณุชุฎุฏุงู… Cython ุŒ ูŠู…ูƒู†ู†ุง ุญู„ ุงู„ุนุฏูŠุฏ ู…ู† ุงู„ู…ุดุงูƒู„. ุจุงู„ู†ุณุจุฉ ุฅู„ู‰ ุจุนุถ ู…ุซูŠู„ุงุช ุงู„ูƒูˆุฏ C ููŠ ุจูŠุซูˆู† ุŒ ูุฅู†ู‡ ูŠู†ุงุณุจ ุงู„ู…ุดูƒู„ุฉ ุจุดูƒู„ ุนุงู… ูˆุฌุฒุฆูŠู‹ุง ู…ุน ูˆุงุฑุฏุงุช ุงู„ู…ูƒุชุจุฉ.


ุฏุนูˆู†ุง ู†ู„ู‚ูŠ ู†ุธุฑุฉ ุนู„ู‰ ู…ุซุงู„ ุจุณูŠุท ู…ู† ุงู„ูˆุซุงุฆู‚ ุงู„ุฑุณู…ูŠุฉ.


from __future__ import print_function def fib(n): """Print the Fibonacci series up to n.""" a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a + b print() 

ุงุญูุธ ู‡ุฐุง ุงู„ู…ู„ู ูƒู€ fib.pyx .
.pyx ู‡ูˆ ุชู†ุณูŠู‚ ุฎุงุต ู„ู…ู„ูุงุช Cython ุŒ ูˆุงู„ุฐูŠ ูŠุดุจู‡ .c ู„ู„ุฑู…ุฒ C ูˆูŠุญุชูˆูŠ ุนู„ู‰ ุจุนุถ ุงู„ูˆุธุงุฆู. ูŠูˆุฌุฏ ุฃูŠุถู‹ุง .pxd ุŒ ููŠ C ูŠูƒูˆู† ู‡ูˆ .h ูˆูŠุญุชูˆูŠ ุนู„ู‰ ูˆุตู ู„ู„ูˆุธุงุฆู ุŒ ุงู„ู‡ูŠุงูƒู„ ุŒ ุฅู„ุฎ.


ู„ู„ุชูุงุนู„ ุจุทุฑูŠู‚ุฉ ู…ุง ู…ุน ูˆุธูŠูุฉ fib ุŒ ู†ุญุชุงุฌ ุฅู„ู‰ "ุชุฑุฌู…ุฉ" ุงู„ูƒูˆุฏ. ู„ู„ู‚ูŠุงู… ุจุฐู„ูƒ ุŒ ู‚ู… ุจุฅู†ุดุงุก setup.py ุจุงุณุชุฎุฏุงู… ู‡ุฐุง ุงู„ู…ุญุชูˆู‰.


 from distutils.core import setup from Cython.Build import cythonize setup( ext_modules=cythonize("fib.pyx"), ) 

ุจุนุฏ ุชุดุบูŠู„ python3 setup.py build_ext --inplace ูŠู…ูƒู†ูƒ ุงุณุชูŠุฑุงุฏู‡ ููŠ ุจูŠุซูˆู† ู…ู†ุชุธู… ูˆุงู„ุงุณุชู…ุชุงุน ุจุณุฑุนุฉ ุงู„ุนู…ู„ ู…ุซู„ ุทุจูŠุนูŠ ู„ุบุงุช ู…ุชุฑุฌู…ุฉ.


 import fib fib.fib(2000) 

ู„ูƒู† ู‡ู†ุง ูƒุชุจู†ุง ุดูุฑุฉ Python ูˆู‚ู…ู†ุง ุจุชุญูˆูŠู„ู‡ุง ุฅู„ู‰ C ุŒ ูˆู„ูƒู† ู…ุงุฐุง ุนู† ูƒุชุงุจุฉ ุดูุฑุฉ C ูˆุชุดุบูŠู„ู‡ุง ููŠ PythonุŸ


ู„ูŠุณุช ู…ุดูƒู„ุฉ ู†ุญู† ู†ู†ุดุฆ ู…ุฌู„ุฏู‹ุง ุฌุฏูŠุฏู‹ุง ุŒ ูˆููŠ ุงู„ุฏุงุฎู„ ู†ู‚ูˆู… ุจุฅู†ุดุงุก ู…ุฌู„ุฏ lib ุงู„ุฐูŠ lib/include ูˆ lib/src ุŒ ููŠ ุงู„ูˆุงู‚ุน ุŒ ูุฅู† ูƒู„ ู…ู† ุนู…ู„ ู…ุน C ูŠุนุฑู ุจุงู„ูุนู„ ู…ุงุฐุง ุณูŠูƒูˆู† ู‡ู†ุงูƒ. ููŠ ุงู„ู…ุฌู„ุฏ ุงู„ุฑุฆูŠุณูŠ ุŒ ู‚ู… ุจุฅู†ุดุงุก ู…ุฌู„ุฏ python_wrap ุขุฎุฑ.


ุฏุนู†ุง struct.h ุฅู„ู‰ lib/include ูˆู‚ู… ุจุฅู†ุดุงุก struct.h ุŒ ุญูŠุซ struct.h ูˆุธูŠูุฉ ูˆุงุญุฏุฉ ูˆู†ุฑู‰ ูƒูŠููŠุฉ ุงู„ุชุนุงู…ู„ ู…ุน ุงู„ู‡ูŠุงูƒู„ ููŠ C ุฅู„ู‰ Cython.


 typedef struct struct_test{ int a; int b; } struct_test; int minus(struct_test a); 

ู„ู†ู‚ู… ุจุฅู†ุดุงุก ู…ู„ู ุขุฎุฑ ุŒ ูˆุงู„ุฐูŠ include.h ุนู„ูŠู‡ include.h ุŒ ูˆุณูŠูƒูˆู† ู„ู‡ ูˆุธูŠูุฉ ุฃุฎุฑู‰ ูˆุงุณุชูŠุฑุงุฏ ุงู„ุจู†ูŠุฉ ู…ู† struct.h


 #include "struct.h" int sum(struct_test param_in_struct); 

ุณู†ู‚ูˆู… ุงู„ุขู† ุจูˆุตู ู‡ุฐู‡ ุงู„ูˆุธุงุฆู ููŠ ู…ู„ู lib/src/test_main.c


 #include "include.h" int sum(struct_test param_in_struct){ return param_in_struct.a+param_in_struct.b; } int minus(struct_test param_in_struct){ return param_in_struct.a-param_in_struct.b; } 

ู†ุนู… ุŒ ุฃู†ุง ู„ุง ุฃุฏุนูŠ ุฃู† ุฃูƒูˆู† ุฃุตู„ูŠู‹ุง ู„ู„ุฃุณู…ุงุก ุงู„ู…ุชุบูŠุฑุฉ ุŒ ู„ูƒู†ู†ุง ุงู†ุชู‡ูŠู†ุง ุชู‚ุฑูŠุจู‹ุง ู…ู† ุงู„ุฌุฒุก C. ู…ุงุฐุง ุจุนุฏุŸ ุฃุถู Makefile ุŒ ุฃูˆ ุจุงู„ุฃุญุฑู‰ CMake. ููŠ ุงู„ู…ุฌู„ุฏ lib ุŒ ู‚ู… ุจุฅู†ุดุงุก CMakeLists.txt .


 set (TARGET "mal") include_directories( include src ) set (SOURCES ./src/test_main.c ) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") add_library(${TARGET} SHARED ${SOURCES}) target_link_libraries(${TARGET} ${LINKLIBS}) add_library(${TARGET}static STATIC ${SOURCES}) target_link_libraries(${TARGET}static ${LINKLIBS}) 

ู…ู† ุงู„ุฏู„ูŠู„ ุงู„ุฑุฆูŠุณูŠ ุŒ ู†ุญุชุงุฌ ุฅู„ู‰ ุงู„ุฅุดุงุฑุฉ ุฅู„ู‰ ุฃู† ู„ุฏูŠู†ุง ู…ุดุฑูˆุนู‹ุง ู„ุชุฌู…ูŠุนู‡ ููŠ ู…ุฌู„ุฏ lib . ุฅู†ุดุงุก ู…ู„ู CMakeLists.txt ุขุฎุฑ ุŒ ูˆู„ูƒู† ุจุงู„ูุนู„ ููŠ ุงู„ุฌุฐุฑ.


 cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR) cmake_policy(VERSION 2.8) project( TEST ) set (CMAKE_C_FLAGS "-Werror -Wall -Wextra -Wno-unused-parameter -D_GNU_SOURCE -std=c11 -O3 -g ${CMAKE_C_FLAGS}") add_custom_target( ReplicatePythonSourceTree ALL ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ReplicatePythonSourceTree.cmake ${CMAKE_CURRENT_BINARY_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) include( GNUInstallDirs ) add_subdirectory(lib) 

ุฃุณุชุฎุฏู… ู‡ู†ุง ู…ู„ูู‹ุง ุตุบูŠุฑู‹ุง ูŠู†ู‚ู„ ุจู†ูŠุฉ ู…ุฌู…ู‘ุน Python ุฅู„ู‰ ุฏู„ูŠู„ ุงู„ุจู†ูŠุฉ ุญุชู‰ ุชุชู…ูƒู† ู…ู† ุชุฑุฌู…ุฉ ู…ู„ูุงุช Python. ู‚ุฏ ู„ุง ูŠูƒูˆู† ู‡ุฐุง ุถุฑูˆุฑูŠู‹ุง ุฅุฐุง ู‚ู…ุช ุจุชู…ุฑูŠุฑ ุงู„ู…ุณุงุฑุงุช ุงู„ู†ุณุจูŠุฉ ุฅู„ู‰ ุฏู„ูŠู„ include ูˆุงู„ู…ูƒุงู† ุงู„ุฐูŠ ุณุชูƒูˆู† ููŠู‡ ุงู„ู…ูƒุชุจุฉ. ุนู„ู‰ ุณุจูŠู„ ุงู„ู…ุซุงู„ ุŒ ุฅุฐุง ูƒุงู†ุช ุงู„ู…ูƒุชุจุฉ ู‚ุฏ ุชู… ุชุฌู…ูŠุนู‡ุง ูˆุชุซุจูŠุชู‡ุง ุจุงู„ูุนู„ ููŠ ุงู„ู†ุธุงู… ุŒ ูุณู†ู‚ูˆู… ุจุชุนูŠูŠู† ุงู„ู…ุณุงุฑุงุช ุฅู„ู‰ ุฏู„ุงุฆู„ ุงู„ู†ุธุงู… ุŒ ูˆู„ูƒู† ุงู„ู…ุฒูŠุฏ ููŠ ู‡ุฐุง ู„ุงุญู‚ู‹ุง.


cmake / ReplicatePythonSourceTree.cmake
 # Note: when executed in the build dir, then CMAKE_CURRENT_SOURCE_DIR is the # build dir. file( COPY setup.py DESTINATION "${CMAKE_ARGV3}" FILES_MATCHING PATTERN "*.py" ) file( COPY lib/src lib/include DESTINATION "${CMAKE_ARGV3}") file(GLOB MY_WRAP "python_wrap/*" ) file( COPY ${MY_WRAP} DESTINATION "${CMAKE_ARGV3}") 

ู‚ุจู„ ุชุฌู…ูŠุน ู…ุดุฑูˆุนู†ุง ุŒ ุฏุนูˆู†ุง ู†ู„ู‚ูŠ ู†ุธุฑุฉ ุนู„ู‰ ุฌุฒุก ุจูŠุซูˆู†. ููŠ ู…ุฌู„ุฏ python_wrap ุจุฅู†ุดุงุก ู…ู„ููŠู† main.pxd ูˆ main.pyx . ููŠ main.pxd ู†ุญุชุงุฌ ุฅู„ู‰ ูˆุตู ู…ุง ู„ุฏูŠู†ุง ููŠ ู…ู„ูุงุช *.h .


 cdef extern from "include/include.h": ctypedef struct struct_test: int a int b int sum(struct_test param_in_struct); int minus(struct_test param_in_struct); 

ุจุงุณุชุฎุฏุงู… cdef extern from "include/include.h" ุŒ ู†ุดูŠุฑ ุฅู„ู‰ ุงู„ู…ู„ู ุงู„ุฐูŠ cdef extern from "include/include.h" . ุจุนุฏ ุฐู„ูƒ ุŒ ูŠุฃุชูŠ ุจู†ุงุก ctypedef struct struct_test: ูˆุตู ู„ู„ู‡ูŠูƒู„ ุจุญูŠุซ ูŠู…ูƒู† ุงุณุชุฎุฏุงู…ู‡ ู…ู† ูƒูˆุฏ Python. ููŠ ุงู„ู†ู‡ุงูŠุฉ ุŒ ููŠ ุงู„ูˆุงู‚ุน ุŒ ูˆุตู ูˆุธูŠูุชูŠู†. ุฃุฑูŠุฏ ุฃู† ุฃุดูŠุฑ ุฅู„ู‰ ุฃู†ู†ุง ุจุญุงุฌุฉ ุฅู„ู‰ ูˆุตู ูƒู„ ู…ุง ู‡ูˆ ู…ูˆุฌูˆุฏ ููŠ include.h ุŒ ุฅุฐุง ูƒุงู† ูŠุณุชูˆุฑุฏ ุจู†ูŠุฉ ูˆูˆุธูŠูุฉ ู…ู† ู…ู„ู ุฑุฃุณ ุขุฎุฑ ุŒ ูุฅู†ู†ุง ู†ุนุชู‚ุฏ ุฃู† ูƒู„ ู‡ุฐุง ู…ูˆุฌูˆุฏ ููŠ ู…ู„ู ูˆุงุญุฏ.


ููŠ main.pyx ู†ูƒุชุจ ูˆุธุงุฆู ุงู„ุงู†ุชู‚ุงู„ ู…ู† Python ุฅู„ู‰ C. ู‡ุฐุง ู„ูŠุณ ุถุฑูˆุฑูŠู‹ุง ุŒ ูˆู„ูƒู† ู„ู…ุงุฐุง ูŠุชู… ุชุญู…ูŠู„ ูƒูˆุฏ Python ุจู‡ูŠุงูƒู„ C. ู„ุฅู†ุดุงุก ู‡ูŠูƒู„ ุŒ ูŠูƒููŠ ุชุนุฑูŠู ู‚ุงู…ูˆุณ ุจูƒู„ ุงู„ู…ุนู„ู…ุงุช.


 from main cimport sum, minus def sum_py(int x, int y): return sum({"a":x,"b":y}) def minus_py(int x, int y): return minus({"a":x,"b":y}) 

ุงู„ุขู† ู†ุญู† ุจุญุงุฌุฉ ุฅู„ู‰ ุฌุนู„ ูƒู„ ุฐู„ูƒ ูŠุฃุชูŠ ู…ุนุง. ุฃุถู ู…ู„ู setup.py ุฅู„ู‰ ุฌุฐุฑ ุงู„ู…ุดุฑูˆุน ุŒ ูƒู…ุง ูุนู„ู†ุง ู…ู† ู‚ุจู„.


 from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext ext_modules = [Extension('main', ['main.pyx'], libraries=['mal'], library_dirs=['lib/'])] setup(name = 'work extension module', cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules) 

ู…ู† ุฃุฌู„ ุชุฑุฌู…ุฉ ุฑู…ุฒ C ูˆุชุฌู…ูŠุน ู…ูƒุชุจุชู†ุง ุŒ ุณู†ู‚ูˆู… ุจุฅู†ุดุงุก ุจุฑู†ุงู…ุฌ ู†ุตูŠ ุจุณูŠุท ู„ู„ุจุงุด.


 #!/bin/sh rm -rf build; mkdir build && cd build cmake .. && make $@ python3 setup.py build_ext -i 

ู†ุญู† ุฅุทู„ุงู‚ ูˆุงู„ุชุญู‚ู‚


 $ sh build.sh $ python3 > import build.main as main > dir(main) [.... 'minus_py', 'sum_py'] > main.minus_py(10,2) 8 > main.sum_py(10,2) 12 

Ctypesgen


ูƒุงู† ุงู„ู…ุซุงู„ ุงู„ุณุงุจู‚ ุจุณูŠุทู‹ุง ูˆู…ุจุงุดุฑู‹ุง ุŒ ู„ูƒู† ู…ุงุฐุง ู„ูˆ ุงุญุชุฌุช ุฅู„ู‰ ุงู„ุชูุงู ู…ูƒุชุจุฉ ูƒุจูŠุฑุฉ ุฌุฏู‹ุง ุŒ ูุงูƒุชุจ ุฌู…ูŠุน ู…ู„ูุงุช .pxd ุจูŠุฏูŠูƒ ู„ูุชุฑุฉ ุทูˆูŠู„ุฉ ุฌุฏู‹ุง ูˆุตุนุจุฉ ุŒ ู„ุฐู„ูƒ ูŠูˆุฌุฏ ุณุคุงู„ ู…ุนู‚ูˆู„ ุŒ ู…ุง ุงู„ุฐูŠ ูŠู…ูƒู† ุงุณุชุฎุฏุงู…ู‡ ู„ุฃุชู…ุชุฉ ุงู„ุนู…ู„ูŠุฉุŸ


ู†ุญู† git clone https://github.com/davidjamesca/ctypesgen.git ู…ุณุชูˆุฏุน git clone https://github.com/davidjamesca/ctypesgen.git . ุงู†ุชู‚ู„ ุฅู„ู‰ build/lib/ ุงู„ู…ูƒุชุจุฉ ุงู„ุชูŠ ุชู… ุฅู†ุดุงุคู‡ุง ู…ุณุจู‚ู‹ุง ูˆุชุดุบูŠู„ ุงู„ุจุฑู†ุงู…ุฌ ุงู„ู†ุตูŠ.


 python3 ~/ctypesgen/run.py -lmal ../include/*.h -o main_wrap.py 

ุจุนุฏ ุฐู„ูƒ ุŒ ู†ุชุญู‚ู‚ ู…ู† ุงู„ุนู…ู„.


 $ python3 > import main_wrap as main > dir(main) [... 'struct_test', 'minus', 'sum'] > main.sum(main.struct_struct_test(1,2)) 3 > main.minus(main.struct_struct_test(1,2)) -1 

ุญุณู†ู‹ุง ุŒ ุจุงู„ุนูˆุฏุฉ ุฅู„ู‰ ู…ุณุฃู„ุฉ ุงู„ู…ูƒุชุจุงุช ุงู„ู…ุซุจุชุฉ ุจุงู„ูุนู„ ุŒ ูู„ู†ูุชุฑุถ ุฃู†ู†ุง ู†ุฑูŠุฏ ุฅู†ุดุงุก ุบู„ุงู ุนู„ู‰ ู…ูƒุชุจุฉ ู†ูŠูˆู† (ุงู„ุชูŠ ุชู… ุชุซุจูŠุชู‡ุง ุจุงู„ูุนู„ ุนู„ู‰ ุงู„ู†ุธุงู… ุจุฃูŠ ุทุฑูŠู‚ุฉ ู…ู„ุงุฆู…ุฉ) ุŒ ูƒู…ุง ู‡ูˆ ู…ูˆุถุญ ููŠ Readme Stypesgen.


 $ ctypesgen.py -lneon /usr/local/include/neon/ne_*.h -o neon.py $ python > import neon > dir(neon) [...,'sys', 'time_t', 'union_ne_session_status_info_u', 'wstring_at'] 

ุฃุฎูŠุฑู‹ุง ุŒ ุฑุงุจุท ุฅู„ู‰ ุฌูŠุซุจ ุŒ ูƒูŠู ูŠู…ูƒู† ุฃู† ูŠูƒูˆู† ุจุฏูˆู†ู‡.

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


All Articles