Я хочу написать оболочку Python для библиотеки C ++. Часть, которую я хочу, является объектом изображения c ++ для массива. Моей первоначальной мыслью было создать PyBuffer
используя Python C API и с помощью SWIG генерировать привязки. numpy.frombuffer
может затем обработать pybuffer, который фактически содержит изображение. Все идет нормально. Но когда я читаю о python.memap
все изменилось, и я хочу знать, его хороший выбор для использования python.memap
Объект C вместо PyBuffer
объект?
Какие здесь плюсы и минусы? Изображения, обрабатываемые библиотекой c ++, могут быть очень большими. ~ 4 ГБ для одного примера.
В соответствии с просьбой, минимальный пример согласно SciPy ‘Поваренная книга:
Файл tst.i
файл интерфейса SWIG, в котором уже есть код C ++ для динамического выделения 100 doubles
, Также есть функция для печати содержимого массива в stdout
реализовано:
%module(docstring="A Simple Numpy Memview example") tstI
%{
#define SWIG_FILE_WITH_INIT
// Her comes the C-code:
#include<iostream>
double *x = NULL;
void __call_at_begining() {
std::cout << "__call_at_begining() ..." << std::endl;
x = new double(100);
for(int i=0; i<100;i++) // fill x with some values
x[i] = i*10;
}
void __call_at_end(void) {
std::cout << "__call_at_end() ..." << std::endl;
if (x != NULL)
free(x);
}
// The interface for the memory view:
void view_x(double** d, int* d_n) {
*d = x;
*d_n = 100;
}
// dump context to stdout:
void print_x() {
std::cout << "x = ";
for(int i=0; i<100;i++)
std::cout << x[i] << " ";
std::cout << std::endl;
}
%}%include "numpy.i"
%init %{
import_array();
__call_at_begining();
%}
%inline %{
void finalize(void) {
__call_at_end();
}
%}
// This is the SWIG magic:
%apply (double** ARGOUTVIEW_ARRAY1, int *DIM1) {(double** d, int* d_n)}
// Here's the Interface decalartion for Python:
void view_x(double** d, int* d_n); // SWIG declaration
void print_x();
мне нравится Cmake, так вот минимальный CMakeLists.txt
файл для использования SWIG (протестирован под Debian Sid), сборка с cmake .
а также make
:
# This is a CMake example for Python
cmake_minimum_required(VERSION 2.8)
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} )
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(tstI.i PROPERTIES CPLUSPLUS ON)
SET_SOURCE_FILES_PROPERTIES(tstI.i PROPERTIES SWIG_FLAGS "-includeall")
SWIG_ADD_MODULE(tstI python tstI.i )
SWIG_LINK_LIBRARIES(tstI ${PYTHON_LIBRARIES})
В следующем примере сеанса Python с использованием оболочки:
In [1]: import numpy as np
In [2]: import tstI # loads module
__call_at_begining() ...
In [3]: y = tstI.view_x() # get memory view
In [4]: y[:10]
Out[4]: array([ 0., 10., 20., 30., 40., 50., 60., 70., 80., 90.])
In [5]: y[:10] = np.zeros(10)
In [6]: tstI.print_x() # dump memory contents
x = 0 0 0 0 0 0 0 0 0 0 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 260
270 280 290 300 310 320 330 340 350 360 370 380 390 400 410 420 430 440 450 460 470 480 490
500 510 520 530 540 550 560 570 580 590 600 610 620 630 640 650 660 670 680 690 700 710 720
730 740 750 760 770 780 790 800 810 820 830 840 850 860 870 880 890 900 910 920 930 940
950 960 970 980 990