Mam problemy z prawidłowym zainicjowaniem interfejsu NumPy C API. Wydaje mi się, że udało mi się wyizolować problem polegający na wywołaniu import_array
z innej jednostki tłumaczeniowej, ale nie wiem, dlaczego to powinno mieć znaczenie.Segfault, gdy import_array nie znajduje się w tej samej jednostce tłumaczeniowej
minimalna przykład praca:
header1.hpp
#ifndef HEADER1_HPP
#define HEADER1_HPP
#include <Python.h>
#include <numpy/npy_3kcompat.h>
#include <numpy/arrayobject.h>
void initialize();
#endif
file1.cpp
#include "header1.hpp"
void* wrap_import_array()
{
import_array();
return (void*) 1;
}
void initialize()
{
wrap_import_array();
}
file2.cpp
Polecenia#include "header1.hpp"
#include <iostream>
void* loc_wrap_import_array()
{
import_array();
return (void*) 1;
}
void loc_initialize()
{
loc_wrap_import_array();
}
int main()
{
Py_Initialize();
#ifdef USE_LOC_INIT
loc_initialize();
#else
initialize();
#endif
npy_intp dims[] = {5};
std::cout << "creating descr" << std::endl;
PyArray_Descr* dtype = PyArray_DescrFromType(NPY_FLOAT64);
std::cout << "zeros" << std::endl;
PyArray_Zeros(1, dims, dtype, 0);
std::cout << "cleanup" << std::endl;
return 0;
}
Kompilator:
g++ file1.cpp file2.cpp -o segissue -lpython3.4m -I/usr/include/python3.4m -DUSE_LOC_INIT
./segissue
# runs fine
g++ file1.cpp file2.cpp -o segissue -lpython3.4m -I/usr/include/python3.4m
./segissue
# segfaults
I zostały przetestowane z Clang 3.6.0 GCC 4.9.2, Python 2,7 Python 3.4 (z odpowiednio zmodyfikowaną wrap_import_array
, ponieważ różni się od Pythonie 2 .x i 3.x). Różne kombinacje dają taki sam wynik: jeśli nie zadzwonię pod numer loc_initialize
, program ulegnie uszkodzeniu w wywołaniu PyArray_DescrFromType
. Mam wersję NumPy 1.8.2. Dla porównania uruchamiam to w Ubuntu 15.04.
Co mnie najbardziej zaskakuje, to this C++ NumPy wrapper wydaje się uciec dzwoniąc pod numer import_array
w innej jednostce tłumaczeniowej.
Czego mi brakuje? Dlaczego muszę zadzwonić pod numer import_array
z tej samej jednostki tłumaczeniowej, aby rzeczywiście zadziałała? Co ważniejsze, jak mogę go uruchomić, gdy zadzwonię pod numer import_array
z innej jednostki tłumaczeniowej, takiej jak opakowanie Boost.NumPy?
Czy możesz podzielić się definicją MYLIBRARY_ARRAY_API? Dzięki. – ssk
MYLIBRARY_ARRAY_API to tylko przykładowa nazwa używana do przechowywania wewnętrznych buforów NumPy. Nie jest to makro, ale powinno być unikalne dla twojej aplikacji/biblioteki, aby zapobiec konfliktowi z innymi bibliotekami. – helloworld922