Skip to content

Instantly share code, notes, and snippets.

@CiaranWelsh
Last active March 18, 2021 15:13
Show Gist options
  • Save CiaranWelsh/183770c0e420222d5884cf162db67535 to your computer and use it in GitHub Desktop.
Save CiaranWelsh/183770c0e420222d5884cf162db67535 to your computer and use it in GitHub Desktop.
How to wrap a C++ std::pair using swig to Python
include(UseSWIG)
set_property(SOURCE SwigPairExample.i PROPERTY CPLUSPLUS ON)
set_property(SOURCE SwigPairExample.i PROPERTY SWIG_FLAGS "-py3" "-debug-classes" "-debug-typedef")
swig_add_library(SwigPairExample
LANGUAGE python
TYPE MODULE
SOURCES SwigPairExample.i SwigPairExample.h)
set_target_properties(SwigPairExample
PROPERTIES LANGUAGE CXX)
target_include_directories(SwigPairExample PUBLIC
${Python_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
)
target_link_libraries(SwigPairExample PUBLIC ${Python_LIBRARIES})
install(TARGETS SwigPairExample DESTINATION SwigPairExample)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/SwigPairExample.py DESTINATION SwigPairExample)
#ifndef SwigPairExample
#define SwigPairExample
#include <utility> // for std::pair
typedef std::pair<double, double> DoublePair ;
class A {
public:
A() : pair_(DoublePair(6.3, 4.9)){};
DoublePair getPair(){
return pair_;
}
private:
DoublePair pair_;
};
#endif //SwigPairExample
%module SwigPairExample
%{
#include <utility>
#include "SwigPairExample.h"
typedef std::pair<double, double> DoublePair;
%}
%include "std_pair.i"
// the typedef works as expected
typedef std::pair<double, double> DoublePair;
// If we want access to DoublePair directly in python we must declare the template here
%template(DoublePair) std::pair<double, double>;
class A {
public:
A();
std::pair<double, double> getPair();
// note, you can also just include SwigPairExample.h
};
import unittest
import SwigPairExample as swig_api
class TestSwigPairExample(unittest.TestCase):
def setUp(self) -> None:
pass
def test_class_A_available(self):
self.assertIn("A", dir(swig_api))
def test_DoublePair_available(self):
self.assertIn("DoublePair", dir(swig_api))
def test_CreateA(self):
a = swig_api.A()
print(a)
print(type(a))
self.assertIsInstance(a, swig_api.A)
def test_getDoublePairFromA(self):
"""
Check that the type returned from getPair is now a tuple
:return:
"""
a = swig_api.A()
doublePair = a.getPair()
print(doublePair, type(doublePair))
self.assertIsInstance(doublePair, tuple)
def test_DoublePair_is_tuple(self):
"""
in test_getDoublePairFromA, the DoublePair was converted from
a DoublePair to a tuple. However, using the DoublePair directly
does not have the same behaviour - couldn't tell you why.
:return:
"""
tup = swig_api.DoublePair()
print(tup)
print(type(tup))
self.assertIsInstance(tup, tuple)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment