0

I have a C++ library that contains a class that is constructed using a reference to a struct:

myclass.hpp:

className::className (params& pars): memberInitList 
{
//some code that modifies state of params
}

My swig interface file looks like

myInterface.i:

%module MyLibrary
%{
     #include "myclass.hpp"
%}

%include "include/myclass.hpp"

according to section 33.3.9 of the SWIG documentation, SWIG should be able to handle this case just fine, but when executing the resulting python package, I get the error:

TypeError: in method 'new_className', argument 1 of type 'params &'

SWIG should be able to handle the pass-by-reference just fine, so I'm not sure what is the issue here. Any help would be greatly appreciated!

edit: I have already looked around the internet for possible solutions, including the SWIG documentation, but no solution has worked. I have tried

%include <typemaps.i>
%apply params &INPUT { params& params}
Binary::Binary(params& params)

but this doesnt work.

edit: MWE Heres a very minimal working example that is the basic working of my code and reproduces exactly my error:

example.hpp

#ifndef included
#define included
#include <vector>
#include <iostream>
using high_prec_t=double; //boost::multiprecision::cpp_dec_float<25>;
struct tmpStruct {
    high_prec_t x { 0. };
    std::string y { "hello" };
    int z { 0 };
    std::vector<high_prec_t> w{};
    double f{0.};
};
class tmpClass
{
    protected:
        high_prec_t m_x;
        std::string m_y;
        int m_z;
        std::vector<high_prec_t> m_w;
        double m_f;
    public:
    tmpClass(tmpStruct& myStruct);

    high_prec_t myFun();
};
#endif 

example.cpp

#include "example.hpp"
#include <iostream>
tmpClass::tmpClass(tmpStruct& myStruct): m_x { myStruct.x }, m_y { myStruct.y }, m_z { myStruct.z }, m_w { myStruct.w }{ m_f = myStruct.f; };
high_prec_t tmpClass::myFun()
{
    return m_f*m_x;
};

example.i

%module example
%{
    #include "example.hpp"
%}
%include "example.hpp"
6
  • The first result in a Google search shows the duplicate: Swig: How to wrap double& (double passed by reference)? Commented Oct 5, 2023 at 12:22
  • That question uses a simple double type, while I am using my own struct Commented Oct 6, 2023 at 5:59
  • You used INPUT but it's wrong. You take arguments by (non-const) reference, I would expect OUTPUT (or INOUT) instead. Commented Oct 6, 2023 at 8:35
  • As for using a struct/class or a numeric type, it works the same with SWIG. This other duplicate does it with std::string which is a struct/class. Commented Oct 6, 2023 at 8:37
  • The casting doesn't work for some reason. You will have to compile the wrapper with -g and run it in the debugger. Set a breakpoint on SWIG_Python_ConvertPtr and check what is the problem. The problem is not obvious from what you have posted and it is likely elsewhere. Commented Oct 6, 2023 at 8:49

1 Answer 1

0

ah, I figured out the issue thanks to this similar question. the issue was, in the python interpreter, I was not calling the struct as

example.tmpStruct()

but rather

example.tmpStruct

so the structure was not being initialized. Initializing the structure properly and passing it to the class constructor works as intended.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.