What a good way to open a C ++ class that provides an array type interface for use with numpy (scipy)?
By a massive interface, I mean something like:
//file:Arr.h class Arr{ public: int n_rows; int n_cols; float* m_data; Arr(int r, int c, float v); virtual ~Arr(); float get(int i, int j); void set(int i, int j, float v); long data_addr(){ return (long)(m_data); } };
Limitations:
- I'm only interested in classes that store their underlying data as solid flat arrays,
- The class will provide open access to the raw storage (possibly through a function),
- I cannot add specific python code to the C ++ header / source files (we donβt want to have a Python dependency for C ++ code), so any modifications to the C ++ side must be done through SWIG (e.g.
%extend ).
My current approach is to place the pythoncode block in my SWIG .i file, it looks like
%pythoncode{ def arraylike_getitem(self, arg1,arg2 ):
where ArrayLike is a C ++ class that contains numeric data (like a flat array) and provides member functions for getting / setting individual values.
The main disadvantage is step 1. above: I need to make a copy of any fragment that I take from my c-array class. (The main advantage is that when returning numpy, I know that I can use it in any numpy operations I want.)
I can introduce two approaches to improve this:
- Adding (via SWIG
%extend ) additional functions for class c and / or - when the python function returns an array proxy object,
My main hang is not to know which interface needs to be implemented (efficiently) in order to plunge to zero, like a numpy array.
Test case
Here is my test setup:
//file:Arr.h class Arr{ public: int n_rows; int n_cols; float* m_data; Arr(int r, int c, float v); virtual ~Arr(); float get(int i, int j); void set(int i, int j, float v); long data_addr(){ return (long)(m_data); } }; //----------------------------------------------------------- //file Arr.cpp
If I can get this Arr class to work with numpy , then I succeeded.
Edit: From this related question, it looks like this: __array_interface__ will be part of the solution (TBD: how to use it?)