5
votes

I have a C++ CameraManager class that manages a list of Camera objects. The camera objects are managed by a std::list, as shared pointers, i.e. each list item is of type: shared_ptr < Camera > .

I can obtain a Camera from a CameraManager object as

 std::shared_ptr<Camera> c = cameraManager.getCamera();

Creating a Python module using Swig, the above is translated to python code as:

  camera = cameraManager.getCamera()

The camera Python object above, however, don't allow me to access any of the Camera classes functions. Python says is an object of type: 'Swig object of type 'std::shared_ptr *' at ####

Adding the following in the Swig interface file

%include <std_shared_ptr.i>
%shared_ptr(Camera)

before including

%include "aiCamera.h"

don't change the behavior in the resulting Python module. Any ideas what might be missing?

Additional info: The C++ code uses a typedef:

typedef CameraSP std::shared_ptr<Camera>;

The Camera class is derived from a base class, that is virtually empty.

class MVR_API MVRObject
{
public:
                                     MVRObject();
                                     MVRObject(const MVRObject& obj);
    virtual                         ~MVRObject();

};

The code is compiled using VS 2013 and CMake. The CMake code looks like this:

set_source_files_properties(${PyModule}.i PROPERTIES CPLUSPLUS ON)
set_source_files_properties(${PyModule}.i PROPERTIES SWIG_FLAGS "-threads")

SWIG_ADD_LIBRARY(${PyModule}
    TYPE MODULE 
    LANGUAGE python 
    SOURCES ${PyModule}.i
    )


SWIG_LINK_LIBRARIES (${PyModule}
    ${PYTHON_LIB_FOLDER}/Python37.lib    
    dslFoundation
    aimvr
)

# INSTALL PYTHON BINDINGS
# Get the python site packages directory by invoking python
execute_process(COMMAND python -c "import site; print(site.getsitepackages()[0])" OUTPUT_VARIABLE PYTHON_SITE_PACKAGES OUTPUT_STRIP_TRAILING_WHITESPACE)
message("PYTHON_SITE_PACKAGES = ${PYTHON_SITE_PACKAGES}")

SET(SWIG_RUNTIME ${CMAKE_CURRENT_BINARY_DIR}/mvr_swigpyrun.h)
execute_process(COMMAND ${SWIG_EXECUTABLE} -python -external-runtime ${SWIG_RUNTIME})

UPDATE: The problem was not Swig and usage of shared pointers. It was a third party library having its own implementation of shared_ptr. Resolving the shared pointers by namespace names fixed the problem and the resulting Python module started working as expected.

1
Did you meant to do %include "aiCamera.h" instead perhaps?Flexo
hoops, editing the post. It is in fact "%included"Totte Karlsson
What's the smallest complete example that can reproduce this? I'd have answered it already without a bounty if you'd shown that.Flexo
What Flexo said...having an example the reproduces the problem goes a long way to getting an answer.Mark Tolonen
Had been happy to give away bounty for solution. However, while creating a short example, the problem was found. A third party library had its own shared_ptr implementation and had a using directive of it causing two shared pointer classes (with the same name(!) (shared_ptr), but different namespaces) being in the mix. Did not see any warning about it when building. Not sure how to do with this post. Perhaps writing it as an answer may help someone else?Totte Karlsson

1 Answers

1
votes

The question above are dealing with a C/C++ API from Allied Vision, controlling their cameras. They have defined their own shared pointer class and named it using the same name as the std shared pointer class, i.e. shared_ptr.

The client code for this API is using std::shared_ptr's, and at some point the usage of a shared_ptr, without specifying the namespace caused the above problems with Swig. By explicitly specifying the std namespace when using a shared_ptr, the problems were resolved and the resulting swigged objects, using shared pointers, started working perfectly fine.