I want to make the code written in ** C ++ ** into a library that can be called by ** Python **. However, there was a big wall called Cython.
This is a continuation of "Cython" tutorial to make Python explosive: basic configuration.
This time, I will explain how to cythonize when the C ++ code you want to cythonize depends on some C ++ library. This time is the preparation.
The code is listed in "github here", so please take a look.
To do that, you need to edit setup.py
, but it will be easier if you leave Cython once and understand how to write CMakeLists.txt so that C ++ compiles in the first place. ..
I changed the name a little from the previous folder structure.
user@~/Documents/cython_practice> tree .
.
├── cpp_library
│ ├── TestClass1.cpp
│ └── TestClass1.h
├── cython
│ ├── my_library.pyx
│ ├── test_class1.pxd
│ └── test_class1.pyx
└── setup.py
2 directories, 6 files
If you start with a review
setup.py
Is a file for compiling C ++ and cython code to create an object file for the library. By doing this, you will be able to do import my_libarary
from python.
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"
],
language="c++"
)
]
setup(
name = "my_library",
cmdclass = {"build_ext": build_ext},
ext_modules= cythonize(ext_modules)
)
cpp_library
Inside the folder are the libraries I wrote in my C ++. The purpose is to make this TestClass1.cpp, TestClass1.h
Cython so that it can be called from Python.
TestClass1.h
namespace my_library
{
class TestClass1{
public:
TestClass1();
void test_function1();
};
} // namespace my_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;
}
}
cython
In the folder, the code for converting the library written in C ++ to Cython is stored. The pxd
file is like a C ++ header file, and the
pyx``` is like a cpp file.
my_library.pxd
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef cppclass TestClass1:
TestClass1()
void test_function1()
my_library.pyx
import cython
cimport cython
include "test_class1.pyx"
def test():
return TestClass1Cython()
test_class1.pxd
cdef extern from "../cpp_library/TestClass1.h" namespace "my_library":
cdef cppclass TestClass1:
TestClass1()
void test_function1()
test_class1.pyx
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()
python setup.py install
To do. actually,
(myenv) user@~/Documents/cython_practice> python
Python 3.6.7 (default, Nov 16 2019, 21:57:19)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import my_library
>>> test = my_library.test()
>>> test.test_function1_cython()
printed from cpp function
Let's confirm that cythonize is done.
In that situation, I think you will run into the problem of how to write setup.py that cythonize. This time, let's assume that a program written in C ++ depends on the gmp library as an example. gmp library
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
You can compile with.
This time I'm ready so far, so next
--Actually implement the function using gimp, --Compile with CMake --Preparation of setup.py for cythonize
I will like to try.
When I want to make C ++ a library that can be called from python using cython, I want to write an appropriate setup.py in the situation where the C ++ side depends on the library. I'm ready for that.
end.
Recommended Posts