"Cython" -Tutorial, das Python explosiv macht: Wenn C ++ - Code von der Bibliothek abhängt. Schreiben Sie setup.py.

Überblick

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!

Situationserklärung

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)

Cython vorerst

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

Wie werden die abhängigen Bibliotheken in setup.py geschrieben?

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ß. ..

Zusammenfassung

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

"Cython" -Tutorial, das Python explosiv macht: Wenn C ++ - Code von der Bibliothek abhängt. Schreiben Sie setup.py.
"Cython" -Tutorial, das Python explosiv macht: Wenn C ++ - Code von der Bibliothek abhängt. Zuallererst CMake.
"Cython" -Tutorial, um Python explosiv zu machen: Wenn eine Funktion auf der C ++ - Seite überlastet ist.
"Cython" -Tutorial, um Python explosiv zu machen: Übergeben Sie das C ++ - Klassenobjekt an das Klassenobjekt auf der Python-Seite. Teil 2
"Cython" -Tutorial, das Python explosiv macht: Handhabung, wenn Funktionen auf der C ++ - Seite als Referenz übergeben werden.
"Cython" -Tutorial, um Python explosiv zu machen: Übergeben Sie ein C ++ - Klassenobjekt an ein Klassenobjekt auf der Python-Seite. Teil ①
"Cython" Tutorial, um Python explosiv zu machen: Grundkonfiguration
"Cython" -Tutorial, um Python explosiv zu machen: So analysieren Sie die in C ++ - Code definierte Enum-Klasse mit Enum in Python.
Verwendung der C-Bibliothek in Python
Ich möchte C ++ - Code aus Python-Code erstellen!
Bei der Konvertierung von CSV in JSON mit Python bin ich auf einen Zeichencode gestoßen
Machen Sie mit Python einen Haltepunkt auf der c-Ebene
Ich hatte das Gefühl, dass ich den Python-Code nach C ++ 98 portiert habe.
Übergeben Sie die OpenCV-Daten der ursprünglichen C ++ - Bibliothek an Python
So schreiben Sie Code für den Zugriff auf Python dashDB auf Bluemix oder lokal
Ich habe den Code geschrieben, um den Brainf * ck-Code in Python zu schreiben
Versuchen Sie, Python-Code zu schreiben, um Go-Code zu generieren. - Versuchen Sie, JSON-to-Go usw. zu portieren
Führen Sie Python-Code unter C ++ aus (mit Boost.Python).
Umgang mit "^ [[A ^ [[B ^ [[C ^ [[D"]] beim Drücken der Richtungstaste beim Ausführen von Python auf dem Mac
python setup.py testet den Code mit Multiprocess
Stellen Sie die von Eigen of C ++ erstellte Bibliothek mit Boost.Numpy in Python zur Verfügung.
Wenn Sie die Python-Bibliothek nicht deinstallieren können. 'Hogehoge' kann nicht deinstalliert werden. Es wurden keine Dateien zum Deinstallieren gefunden.
Hinweis zur Codierung bei LANG = C in Python
Tipps zum Schreiben werden in Python kurz abgeflacht
Einführung in Python mit Atom (unterwegs)
So schreiben Sie in Error Repoting in Python auf GAE
Eine Geschichte, die beim Versuch, die Python-Version mit GCE zu aktualisieren, hängen blieb
Übergeben von Argumenten beim Aufrufen von Python-Skripten über Blender in der Befehlszeile