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