std::vector member variable as python list
Lars Jahr Røine <[email protected]> Wed, 14 Apr 2021 10:43:38 +0200
| Newsgroups | gmane.comp.programming.swig |
|---|---|
| Message-ID | <CAMUwdg4V_WrJAzDjBspgSHe8jGg6dZS1Tx_RggjsSgBbk+GcpA@mail.gmail.com> |
Hi,
I'm using swig to create wrappers for a C++ library. The main class in the
library has a few public std::vector member variables that I would like to
access as lists in python. I have simplified my real code to the following
header file:
example.h
---------------
#pragma once#include <vector>#if defined _WIN32
#define EXPORT __declspec(dllexport)#else
#define EXPORT#endif
namespace Example {
class EXPORT MyClass {
public:
std::vector<int> my_data{1, 2, 3};
std::vector<int> get_vec();
};
}
and the closest I have gotten is this (using std_vector.i and %naturalvar
in my interface file):
>>> from example import MyClass>>> m = MyClass()>>> m.get_vec()
(1, 3, 5)>>> m.my_data
(1, 2, 3)>>> m.my_data = [9, 8, 7]>>> m.my_data.append(6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
This is close to what I want, but since std_vector.i converts std::vector
to a tuple, it is not possible to append elements to the my_data variable.
If I remove the %naturalvar from *example.i* I can use list methods like
append on my_data. However, I then get an error message if I try to assign
the variable to a python list (since the type of my_data then is a proxy of
a swig object). I have tried adding a typemap to *example.i* file. Then the
get_vec method returned a python list, but the type of my_data did not
change.
%typemap(out) std::vector<int> (PyObject* tmp) %{
tmp = PyList_New($1.size());
for(int i = 0; i < $1.size(); ++i)
PyList_SET_ITEM(tmp,i,PyLong_FromLong($1[i]));
$result = SWIG_Python_AppendOutput($result,tmp);
%}
After doing some research I suspect that I might need to define typemap(in)
and typemap(out) for the type const std::vector<int>&, but I haven't been
able to figure out how they should look. Is creating typemaps the way to go
for this problem, or would you recomend any other strategies? All help is
appreciated. Below are all the files needed to build my example.
example.i
-------------
%module example
%include "stdint.i"
%include "std_vector.i"
%naturalvar;
%{#include <example.h>
%}
%template(int_vector) std::vector<int>;
%include <example.h>
example.cpp
-----------------
#include "example.h"
namespace Example {
std::vector<int> MyClass::get_vec() {
std::vector<int> v{1, 3, 5};
return v;
}
}
CMakeLists.txt
-------------------
cmake_minimum_required(VERSION 3.15)
project(CMakeSwigExample LANGUAGES CXX)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
add_library(example_cpp SHARED example.h example.cpp)
target_compile_features(example_cpp PUBLIC cxx_std_17)
if (UNIX)
set_target_properties(example_cpp PROPERTIES INSTALL_RPATH "$ORIGIN")
endif()
FIND_PACKAGE(SWIG REQUIRED)
INCLUDE(${SWIG_USE_FILE})
FIND_PACKAGE(PythonLibs)
SET(CMAKE_SWIG_FLAGS "")
SET_SOURCE_FILES_PROPERTIES(example.i PROPERTIES CPLUSPLUS ON)
set_property(SOURCE itnfileio.i PROPERTY SWIG_MODULE_NAME example)
SWIG_ADD_LIBRARY(example
TYPE SHARED
LANGUAGE python
SOURCES example.i)
target_include_directories(example
PRIVATE
${PYTHON_INCLUDE_DIRS})
target_link_libraries(example PRIVATE example_cpp ${PYTHON_LIBRARIES})
Regards,
Lars
_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user