2

Solved! - Please check the answer.

I wrote a library where headers and python bindings are auto-generated. For example dummy_bind.cpp for dummy_message.h and each _bind.cpp file has PYBIND11_MODULE call in it for their specific class. There are dozens of other _bind.cpp files for other headers. What should be the module name for each file when calling the PYBIND11_MODULE like:

PYBIND11_MODULE(protocol_name, m)
{
    /// …
}

If I use protocol_name in each PYBIND11_MODULE(protocol_name, m) call, when compiling I get multiple definition error like: multiple definition of PyInit_protocol_name. If I generate special module name for each message like PYBIND11_MODULE(protocol_name_dummy, m) the extension is compiled but I think I need to import each module one by one which is not viable.

Should I do all exports inside a single PYBIND11_MODULE call? Thanks in advance.

1
  • You certainly can't have multiple modules with the same name, you'll need to do something different Commented Feb 25 at 7:13

2 Answers 2

3

I've actually solved this by generating proxy functions in _bind.cpp files. For instance, in message1_bind.cpp I've defined a function void init_message1(pyinit11::module& m) and then in main_bind.cpp I call them all inside PYBIND11_MODULE(protocol_name, m) so I only have only one PYBIND11_MODULE() call. Here's a minimal example to describe the method better:

message1_bind.cpp:

#include <pybind11/pybind11.h>
#include "messages/message_1.h"

void init_message1(pybind11::module& m)
{
    pybind11::class_<protocol_name::Message1>(m, "Message1").def(pybind11::init<>());
    m.def("serialize_message1", &protocol_name::serialize_message_1);
    m.def("deserialize_message1", &protocol_name::deserialize_message_1);
}

And then inside main_bind.cpp

#include <pybind11/pybind11.h>
#include "message1_bind.cpp"
/// ... all other includes

PYBIND11_MODULE(protocol_name, m)
{
    init_message1(m);
    /// init_message2(m) and so on..
}
Sign up to request clarification or add additional context in comments.

Comments

1

Why not solve this on the Python side? Assume you have message types hello and bye that are turned into org.sigsev.proto.hello.HelloMessage and org.sigsev.proto.bye.ByeMessage, respectively.

Then you can define a __init__.py in org/sigsegv/proto with the following contents:

from .hello import HelloMessage
from .bye import ByeMessage

Now the org.sigsegv.proto module will export HelloMessage and ByeMessage.

1 Comment

Hey, thanks for your help. I've posted the solution as an answer.

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.