6

I write a simple code trying to use numpy in C++. My OS is ubuntu16.04, with gcc5.4.0, Python2.7.12 and numpy1.15.0. Here is my codetest2.cpp:

#include "Python.h"
#include "numpy/arrayobject.h"

int main(int argc, char **argv) 
{
    Py_Initialize();     
    import_array(); 

    Py_Finalize(); 
    return 0; 
}

I use a CMakeLists.txt like this:

cmake_minimum_required(VERSION 3.10) 

project(test_python LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_BUILD_TYPE DEBUG)

set(PYTHON_INCLUDE_PATH /usr/include/python2.7)
set(PYTHON_LIBRARY /usr/lib/python2.7/config-x86_64-linux-gnu/libpython2.7.so)
set(NUMPY_INCLUDE_PATH /usr/local/lib/python2.7/dist-packages/numpy/core/include)

include_directories(${PYTHON_INCLUDE_PATH})
include_directories(${NUMPY_INCLUDE_PATH})

add_executable(test_python test2.cpp) 
target_link_libraries(test_python 
    ${PYTHON_LIBRARY}
)

But while I make it, I come up with following compiling error:

/usr/local/lib/python2.7/dist-packages/numpy/core/include/numpy/__multiarray_api.h:1547:144: error: return-statement with no value, in function returning ‘int’ [-fpermissive]
 #define import_array() {if (_import_array() < 0) {PyErr_Print(); PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import"); return NUMPY_IMPORT_ARRAY_RETVAL; } }
                                                                                                                                                ^
/home/camsys/projects/hmr_c/test/test2.cpp:7:5: note: in expansion of macro ‘import_array’
     import_array(); 
     ^

This is weird, because when I use Python3.5 with Numpy1.15.0, everything is ok. Could any one tell me why this error happened and how to solve it?

And I found another similar question asked 4 years ago with no answer Passing C++ array to python. That question was about python3.4, while I am dealing with python2.7.

1 Answer 1

2

import_array() is a macro defined inside /usr/local/lib/pythonX.Y/dist-packages/numpy/core/include/numpy/__multiarray_api.h. During code pre-processing (before compilation), the definition of this macro is expanded and replaced in the main function just like this:

int main(int argc, char **argv) 
{
    Py_Initialize();     
    {
        if (_import_array() < 0) {
            PyErr_Print();
            PyErr_SetString(PyExc_ImportError, "numpy.core.multiarray failed to import");
            return NUMPY_IMPORT_ARRAY_RETVAL;
        }
    }
    Py_Finalize(); 
    return 0; 
}

Now, NUMPY_IMPORT_ARRAY_RETVAL is also a macro defined inside the same file __multiarray_api.h. This macro is defined as NULL for python3 and above, otherwise nothing.

#if PY_VERSION_HEX >= 0x03000000
#define NUMPY_IMPORT_ARRAY_RETVAL NULL
#else
#define NUMPY_IMPORT_ARRAY_RETVAL
#endif

The int main function is supposed to return an integer, but inside the expanded if statement (if the condition _import_array() < 0 is met), it returns either NULL = 0 (#define NULL 0) for python versions >= 3, therefore it works. For python versions < 3, the main function returns nothing, hence the error.

Workaround (for python versions < 3):

void temp_func() {
    import_array();
}

int main(int argc, char **argv) {
    Py_Initialize();     
    temp_func();

    Py_Finalize(); 
    return 0; 
}

Hope, this answers the question.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.