Ich möchte in C ++ geschriebenen Code zu einer Bibliothek machen, die in Python aufgerufen werden kann. Es gab jedoch eine große Mauer namens Cython.
Dies ist das "Cython" -Tutorial, das Python explosiv macht: Wenn C ++ - Code von der Bibliothek abhängt. Zuallererst CMake. Es wird eine Fortsetzung von sein.
Bisher haben wir gesehen, wie Sie mit cmake ein C ++ - Programm, das von der gmp-Bibliothek abhängt, bequem kompilieren können. Von hier aus besteht das Hauptthema darin, den Code zu schreiben, um dieses C ++ - Programm zu cythonisieren und mit setup.py zu kompilieren.
Der hier verwendete Code finden Sie unter github here. Wenn Sie also interessiert sind, schauen Sie bitte!
Im vorherigen Artikel musste ich die Abhängigkeiten meines C ++ - Programms verstehen, um setup.py überhaupt schreiben zu können.
Ich erklärte. Dieses Mal schreibe ich den Code, der die C ++ - Funktion tatsächlich in Cython konvertiert, schreibe setup.py unter Bezugnahme auf die vorherige CMakeLists.txt und kompiliere ihn so, dass er von Python aus aufgerufen werden kann.
Der Code auf der C ++ - Seite ist ebenfalls als Überprüfung enthalten.
cpp_library/TestClass1.h
#include <gmp.h>
namespace my_library
{
class TestClass1{
public:
TestClass1();
void test_function1();
static void gmp_print_test();
};
} // namespace my_library
cpp_library/TestClass1.cpp
#include <iostream>
#include "TestClass1.h"
using namespace std;
namespace my_library{
TestClass1::TestClass1(){};
void TestClass1::test_function1(){
cout << "printed from cpp function" << endl;
}
void TestClass1::gmp_print_test(){
mpz_t test;
mpz_init(test);
mpz_set_ui(test, 1);
gmp_printf("print : %Zd \n", test);
}
}
Wenn Sie eine solche `test.cpp``` haben, stellen Sie sicher, dass Sie sie mit der folgenden
CMakeLists.txt``` kompilieren können.
cpp_library/test.cpp
#include "TestClass1.h"
using namespace my_library;
int main(){
TestClass1::gmp_print_test();
}
cpp_library/CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(TEST VERSION 1.1.0 LANGUAGES CXX)
# Executable will be in ../bin
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
set(CMAKE_CXX_FLAGS "-g -O0 -lgmp")
add_executable(test1
test.cpp
TestClass1.cpp
)
target_sources(test1
PRIVATE
)
target_include_directories(test1 PRIVATE /usr/local/gmp/6_1_2/include/)
target_link_libraries(test1 gmp /usr/local/gmp/6_1_2/lib)
Schreiben Sie zunächst den Cython-Code wie folgt, um die C ++ - Funktion zu verpacken. Wie zuvor war die pxd-Datei die Cython-Header-Datei und die Pyx-Datei die Cython-Programmkörperdatei. Schreiben Sie, um C ++ wie folgt zu verpacken.
cython/test_class1.pxd
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef cppclass TestClass1:
TestClass1()
void test_function1()
void gmp_print_test()
cython/test_class1.pxd
import cython
cimport cython
cdef class TestClass1Cython:
cdef TestClass1* ptr
def __cinit__(self):
self.ptr = new TestClass1()
def __deadaloc(self):
del self.ptr
def test_function1_cython(self):
self.ptr.test_function1()
@staticmethod
def gmp_print_test():
cdef TestClass1 testclass1
testclass1.gmp_print_test()
cython/my_library.pxd
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef cppclass TestClass1:
TestClass1()
void test_function1()
void gmp_print_test()
cython/my_library.pyx
import cython
cimport cython
include "test_class1.pyx"
def test():
return TestClass1Cython()
setup.py
Von hier aus schreiben Sie setup.py deutlich, dass es von der gmp-Bibliothek abhängt.
Wenn Sie bereits wissen, wie man CMakeLists.txt schreibt, ist dies eine einfache Aufgabe. Wie du siehst,
libraries=["gmp"],
library_dirs=["/usr/local/lib", "/usr/local/gmp/6_1_2/lib"],
include_dirs=["/usr/local/gmp/6_1_2/include"],
mögen,
Genau wie beim Schreiben von CMakeLists.txt.
Als Ergebnis habe ich die folgende setup.py erstellt.
setup.py
from setuptools import setup, Extension,find_packages
from Cython.Build import cythonize
from Cython.Distutils import build_ext
from distutils import sysconfig
ext_modules = [
Extension(
"my_library", sources=["./cython/my_library.pyx",
"./cpp_library/TestClass1.cpp"
],
libraries=["gmp"],
library_dirs=["/usr/local/lib", "/usr/local/gmp/6_1_2/lib"],
include_dirs=["/usr/local/gmp/6_1_2/include"],
language="c++",
extra_compile_args=['-std=c++1z',"-lgmp"]
),
]
setup(
name = 'my_library',
cmdclass = {'build_ext': build_ext},
ext_modules = cythonize(ext_modules)
)
Nachdem Sie die obigen Schritte ausgeführt haben, haben Sie das C ++ - Programm, das von der gmp-Bibliothek abhängt, erfolgreich in cython konvertiert.
python setup.Ich habe es mit py install versucht und es wird kompiliert. Ich werde versuchen, es von der Python-Seite richtig aufzurufen.
```bash
(myenv) root@e96f489c2395:/from_local/cython_practice# python
Python 3.6.3 (default, Jan 30 2020, 06:37:54)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_library
>>> my_library.TestClass1Cython.gmp_print_test()
print : 1
groß. ..
Dieses Mal habe ich erklärt, wie man Cythonize verwendet, wenn der Code auf der C ++ - Seite von einer Bibliothek abhängt (im Beispiel die gmp-Bibliothek), und ich konnte ihn tatsächlich kompilieren.
Als Nächstes werde ich erklären, wie ein Klassenobjekt auf der C ++ - Seite an ein Klassenobjekt in Python übergeben wird. Persönlich denke ich, dass die meisten Dinge getan werden können, wenn Sie wissen, wie man es übergibt, also schauen Sie bitte! !!
Wenn Sie es hilfreich finden, würde ich gerne von LGTM, Kommentaren und mehr hören.
Diesmal hier.
Ende.
Recommended Posts