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 der C ++ - Code von der Bibliothek abhängt. Dies ist die Fortsetzung des Vorbereitungsabschnitts.
Der Code ist unter "github hier" aufgeführt. Schauen Sie also bitte vorbei.
Als minimale Ordnerstruktur war es so.
(myenv) user@~/Documents/cython_practice[master]> tree .
.
├── README.md
├── cpp_library
│ ├── TestClass1.cpp
│ └── TestClass1.h
├── cython
│ ├── my_library.pxd
│ ├── my_library.pyx
│ ├── test_class1.pxd
│ └── test_class1.pyx
└── setup.py
Darüber hinaus am Ende des letzten Males
wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.xz &&\
tar xvf gmp-6.1.2.tar.xz &&\
cd gmp-6.1.2 &&\
./configure --prefix=/usr/local/gmp/6_1_2 &&\
make && make check && make install
Ich habe die `` `gmp``` Bibliothek installiert.
Diesmal zuerst
Ich werde bis zu 3 erklären. In Bezug auf 4 werde ich Cython tatsächlich verwenden, um ein C ++ - Programm mit Abhängigkeiten zu kompilieren, damit es von Python aus aufgerufen werden kann, was ich im nächsten Artikel schreiben werde.
gmp
Dies ist der Befehl, wenn die Bibliothek installiert ist.
./configure --prefix=/usr/local/gmp/6_1_2
Hier wird die Objektdatei gespeichert, die beim späteren Kompilieren mit `` `make`` `erstellt wurde, und die Header-Datei, die zum Zeitpunkt von` `make install`` `die Quelle des Projekts ist. Ist der angegebene Befehl.
Wenn nicht angegeben, wird die Objektdatei im Wesentlichen in `` `/ usr / local / lib`` `und die erforderliche Header-Datei (im Grunde eine Header-Datei, die alle für die Bibliothek erforderlichen Programmdateien enthält) gespeichert. ) Wird in `` `/ usr / local / include`` `gespeichert.
Danach wird es von `` `make`` `kompiliert und die von` `` make install` `` kompilierte Objektdatei und Header-Datei werden gespeichert.
Stellen Sie hier sicher, dass die Objektdatei und die Header-Datei der gmp-Bibliothek tatsächlich im angegebenen Ordner gespeichert sind.
```bash
root@e96f489c2395:/# ls /usr/local/gmp/6_1_2/lib/
libgmp.a libgmp.la libgmp.so libgmp.so.10 libgmp.so.10.3.2
root@e96f489c2395:/# ls /usr/local/gmp/6_1_2/include/
gmp.h
Sicherlich befindet sich die Objektdatei unter `/ usr / local / gmp / 6_1_2 / lib```, Die Header-Datei wird unter
`/ usr / local / gmp / 6_1_2 / include``` gespeichert.
cmake
Um ein Programm zu erstellen und zu kompilieren, das sie verwendet, müssen Sie daher mit Bezug auf sie kompilieren. Verwenden Sie zunächst einfach g ++, um ein einfaches Programm zu schreiben und es zu kompilieren.
test.cpp
#include <iostream>
#include <gmp.h>
using namespace std;
void print_test(){
mpz_t test;
mpz_init(test);
mpz_set_ui(test, 1);
gmp_printf("print : %Zd \n", test);
}
int main(){
print_test();
}
Sie müssen nichts über die gmp-Bibliothek wissen, aber da gmp eine Bibliothek ist, die große Ganzzahlen berechnet, weist dieses Programm einem Objekt namens test einfach 1 zu und druckt es aus.
Kompilieren Sie die Bibliothek explizit mit Optionen. Wenn Sie versuchen zu kompilieren, ohne etwas über die Bibliothek zu schreiben, wird natürlich ein Referenzfehler angezeigt.
root@e96f489c2395:/from_local# g++ test.cpp
/tmp/ccZnVmvP.o: In function `main':
test.cpp:(.text+0x1f): undefined reference to `__gmpz_init'
test.cpp:(.text+0x30): undefined reference to `__gmpz_set_ui'
test.cpp:(.text+0x48): undefined reference to `__gmp_printf'
collect2: error: ld returned 1 exit status
Es wird sein. Dies liegt natürlich daran, dass die abhängigen Bibliotheken nicht angegeben werden, sondern durch Lösen,
root@e96f489c2395:/from_local# g++ test.cpp -L/usr/local/gmp/6_1_2/lib -I/usr/local/gmp/6_1_2/include -lgmp
root@e96f489c2395:/from_local# ./a.out
print : 1
Natürlich können Sie so kompilieren.
In diesem Fall gibt `` `-Lden Pfad zur Bibliothek (Objektdatei) an.
-i```Ist eine Kompilierungsoption, die den Pfad zur Header-Datei angibt.
Wenn Sie jedoch mehrere abhängige Bibliotheken haben oder wenn Sie mehrere Programme haben, die Sie schreiben, kann das Kompilieren mit `g ++`
wie diesem ziemlich ärgerlich sein. Bereiten Sie daher CMakeLists.txt vor und kompilieren Sie es einfach.
Erstellen Sie dazu die folgenden `CMakelists.txt
`
cmake . &&Es ist vorzuziehen, mit make zu kompilieren.
Anstatt hier `` `CMakelists.txt`` `wie folgt zu erstellen und mit dem Befehl` `` g ++ `` `und Optionen zu kompilieren,` `` cmake. && make``` Ich werde versuchen, damit zu kompilieren.
#### **`CMakeLists.txt`**
```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
)
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)
root@e96f489c2395:/from_local# cmake .
-- Configuring done
WARNING: Target "test1" requests linking to directory "/usr/local/gmp/6_1_2/lib". Targets may link only to libraries. CMake is dropping the item.
-- Generating done
-- Build files have been written to: /from_local
root@e96f489c2395:/from_local# make
[100%] Built target test1
root@e96f489c2395:/from_local# ./test1
print : 1
Als Wissen, das beim Konvertieren eines C ++ - Programms in Cython erforderlich ist, wurde Folgendes durchgeführt, um die Cythonisierung eines Programms zu erreichen, das von der C ++ - Seite abhängig ist.
Im nächsten Artikel
Diesmal hier.
Ende.