"Cython" tutorial to make Python explosive: Handling when a function on the C ++ side is passed by reference.

Overview

I want to make the code written in C ++ a library that can be called in Python. However, there was a big wall called Cython.

This is "Cython" tutorial to make Python explosive: when a function on the C ++ side has an overload. This is a continuation of.

The code is listed in "github here", so please take a look.

Last time, I explained Cythonization when a function on the C ++ side is overloaded (when the configuration has the same function name but different arguments).

This time, I would like to explain how to handle a function on the C ++ side on the Cython side when passing it by reference instead of passing it by value as an argument. It's not very new, but when you actually try to write Cython, you often get annoyed by errors, so be sure to check it out! !!

Situation explanation

--Since the function on the C ++ side was overloaded, it was solved using a cast like previous article. --The arguments of the function implemented on the C ++ side include those passed by reference. --If the argument is a reference type, an error will occur.

I will actually try it.

cpp_library/TestClass1.h


class TestClass1{
    private:
        TestClass2 property_test_class2;
        EnumForTestClass1 group;

    public:
        //~abridgement
        static void print_vector(vector<int> &x);
        static void print_vector(vector<double> &x);

The difference from the last time is that the argument `` `xof print_vector``` is changed from ** by value to passed by reference **.

cpp_library/TestClass1.cpp


void TestClass1::print_vector(vector<int> &x){
    for(int i=0; i<x.size(); i++){
        cout << x[i] << " ";
    }
    cout << endl;
}

void TestClass1::print_vector(vector<double> &x){
    for(int i=0; i<x.size(); i++){
        cout << x[i] << " ";
    }
    cout << endl;
}

When I try to build this with python setup.py install as usual, I get the following error:


./cython/my_library.cpp:2414:69: error: cannot bind non-const lvalue reference of type 'std::vector<int>&' to an rvalue of type 'std::vector<int>'
     __pyx_t_1 = __Pyx_void_to_None(__pyx_v_testclass1.print_vector(((std::vector<int> )__pyx_t_4))); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error)

The cast should be neat, but I get angry when it comes to passing by reference.

So, as a solution

Create the entity on the spot, not the cast.

What does that mean?

cython/test_class1.pyx


    @staticmethod
    def print_vector(list x):
        cdef:
            TestClass1 testclass1
            vector[int] vec_int
            vector[double] vec_double
        
        if isinstance(x[0], int):
            vec_int.resize(len(x))
            for i in range(len(x)):
                vec_int[i] = <int>x[i]
            return testclass1.print_vector(vec_int)
        elif isinstance(x[0], float):
            vec_double.resize(len(x))
            for i in range(len(x)):
                vec_double[i] = <double>x[i]
            return testclass1.print_vector(vec_double)
        else:
            raise Exception('TypeError')

will do. Now, with `cdef```, create ``` vector [int] and ``` vector [double] `` on the fly and pass it to the function. Maybe the error I just got is passed by reference, but I don't know if it really exists! Don't worry! !! !! I interpret that it was an error.

Therefore, it is good to prepare the entity and reassure it.

Then, as usual, `python setup.py install` will pass the build.

By doing this, by writing the test code as follows,

test.py


import my_library as myl

if __name__ == "__main__":

    cl1 = myl.test()
    x = [1,2,3]
    y = [1.1, 2.2, 3.3]
    cl1.print_vector(x)
    cl1.print_vector(y)

I was able to call the function properly.

(myenv) root@e96f489c2395:/from_local/cython_practice# python test.py 
1 2 3 
1.1 2.2 3.3 

Summary

This time, I explained how to handle the function on the C ++ side when passing by reference instead of passing by value as an argument on the Cython side.

This time around.

end.

Recommended Posts

"Cython" tutorial to make Python explosive: Handling when a function on the C ++ side is passed by reference.
"Cython" tutorial to make Python explosive: When a function on the C ++ side has an overload.
"Cython" tutorial to make Python explosive: Pass a C ++ class object to a class object on the Python side. Part ①
"Cython" tutorial to make Python explosive: Pass the C ++ class object to the class object on the Python side. Part 2
"Cython" tutorial to make Python explosive: When C ++ code depends on the library. Preparation
"Cython" tutorial to make Python explosive: When C ++ code depends on the library. Write setup.py.
"Cython" tutorial to make Python explosive: When C ++ code depends on the library. First of all, CMake.
"Cython" Tutorial to Make Python Explosive: Basic Configuration
"Cython" tutorial to make Python explosive: How to parse an Enum class defined in C ++ code into a Python Enum.
Make a breakpoint on the c layer with python
[Python] Make sure the received function is a user-defined function
Let's use AWS Lambda to create a mechanism to notify slack when the value monitored by CloudWatch is exceeded on Python
[Python] Make the function a lambda function
Extension of Python by C or C ++ (when there are multiple arguments, when passing a list from the Python side)
How to automatically notify by phone when the python system is down
How to deal with "^ [[A ^ [[B ^ [[C ^ [[D"] when you press the arrow keys when executing python on mac
A story that got stuck when trying to upgrade the Python version on GCE
Let's make a leap in the manufacturing industry by utilizing the Web in addition to Python
Add a function to tell the weather of today to slack bot (made by python)
Read the xml file by referring to the Python tutorial
[Python] How to call a c function from python (ctypes)
A super introduction to Django by Python beginners! Part 6 I tried to implement the login function
[C / C ++] Pass the value calculated in C / C ++ to a python function to execute the process, and use that value in C / C ++.
I tried to create a RESTful API by connecting the explosive Python framework FastAPI to MySQL.
Check the argument type annotation when executing a function in Python and make an error
Use Heroku in python to notify Slack when a specific word is muttered on Twitter
Workaround for the problem that sys.argv is not passed when executing a Python script with only the file name in Python2.7 on Windows
Finally ... Make a radio control using python on Raspberry Pi 3! (When the magnet is brought closer, the motor moves and stops automatically)
[Python] How to make a list of character strings character by character
[python] A note when trying to use numpy with Cython
When you want to hit a UNIX command on Python
Write a script in Shell and Python to notify you in Slack when the process is finished
[Python] I tried to make a simple program that works on the command line using argparse.
About the error I encountered when trying to use Adafruit_DHT from Python on a Raspberry Pi
[Introduction to Python] How to split a character string with the split function
How easy is it to synthesize a drug on the market?
[Python] Execution time when a function is entered in a dictionary value
[Python3] Define a decorator to measure the execution time of a function
Build Python environment on Ubuntu (when pip is not the default)
What to do when the value type is ambiguous in Python?
[Python] A simple function to find the center coordinates of a circle
A super introduction to Django by Python beginners! Part 3 I tried using the template file inheritance function
Finally ... Make a radio control using python on Raspberry Pi 3! (The motor moves while the button is pressed)