-1

Please see below C++ code that I am trying to create python bindings for

struct Config {
  int a;
  int b;
};

void myfunction(const Config &config);

Here is what I have so far,

PYBIND11_MODULE(example, m) {
  py::class_<Config>(m, "Config")
    .def_readwrite("a", &Config::a)
    .def_readwrite("b", &Config::b);

  m.def("myfunction", &myfunction);
}

This compiles, but when I attempt to call the python bindings in python,

import example

config = example.Config;
config.a = 1;
config.b = 2;

example.myfunction(config)

I got the below error

TypeError: myfunction(): incompatible function arguments. The following argument types are supported:
    1. (arg0: example.Config) -> None

Invoked with: <class 'example.Config'>

Can someone let me know what is the right way to create python bindings for a function that takes in a struct as an argument?

user3667089
  • 2,996
  • 5
  • 30
  • 56
  • 3
    Typo: `config = example.Config;` -> `config = example.Config()`? – eyllanesc Sep 17 '21 at 06:06
  • @eyllanesc pretty sure it's not, if I did what you suggested, `TypeError: example.Config: No constructor defined!` – user3667089 Sep 17 '21 at 06:09
  • Why don't you declare a default constructor and associate it with py::init? – eyllanesc Sep 17 '21 at 06:11
  • @eyllanesc has provided the answer to the issue as posted (unfortunately as a comment). You pass a class instead of an instance (`Invoked with: ` gives a strong hint of this). Issues with declaring a default constructor sound like a separate issue. But providing the default constructor and then getting the _same_ error, well, code to reproduce that would be useful, because it sounds unlikely. – juanchopanza Sep 17 '21 at 07:19
  • @eyllanesc you are right, I got it to work with your hint. If you write up an answer I will accept it. Thanks. – user3667089 Sep 17 '21 at 16:58
  • @user3667089 Better you post the answer. :-) – eyllanesc Sep 17 '21 at 17:04

1 Answers1

2

As hinted by @eyllanesc, the problem will be solved by adding a default constructor:

PYBIND11_MODULE(example, m) {
  py::class_<Config>(m, "Config")
    .def(py::init<>())
    .def_readwrite("a", &Config::a)
    .def_readwrite("b", &Config::b);

  m.def("myfunction", &myfunction);
}
import example

config = example.Config();
config.a = 1;
config.b = 2;

example.myfunction(config)
user3667089
  • 2,996
  • 5
  • 30
  • 56