Pelagicore / gdbus-codegen-glibmm

Code generator for C++ D-Bus stubs and proxies using Giomm/Glibmm
GNU Lesser General Public License v2.1
23 stars 25 forks source link

Problem with signal sending. #9

Open klukaspl opened 6 years ago

klukaspl commented 6 years ago

Hi, I was successfully generated stubs with methods and signals. I am trying to implement the dbus server using them. As it is quite easy to me to use stubs to implement the methods and call them, I have problem with signals implementation using stubs. I would like to evoke signal when by some external function to populate the string with message that something happened to another process.

Could you please give me any hint how to play with that?

This is part generated stub.cpp I am using:

<signal name="EventNotification">
    <arg name="EventString" type="s"/>
</signal>
void com::my::busname::Processor::EventNotification_emitter(std::string EventString) {
            std::vector<Glib::VariantBase> paramsList;

paramsList.push_back(Glib::Variant<Glib::ustring >::create((EventString)));;

m_connection->emit_signal(
              "/com/my/busname/Processor",
              "com.my.busname.Processor",
              "EventNotification",
              Glib::ustring(),
              Glib::Variant<std::vector<Glib::VariantBase> >::create_tuple(paramsList));
      }

I am trying to call : EventNotification_emmiter("Sample STRING");

This compile but after execution I have Segmentation fault (problem with memory).

EDIT:

void com::my::busname::Processor::EventNotification_emitter(std::string EventString) {
            std::vector<Glib::VariantBase> paramsList;

paramsList.push_back(Glib::Variant<Glib::ustring >::create((EventString)));;
std::cout << "tu jestem" << std::endl;

m_connection->emit_signal(
              "/com/my/busname/Processor",
              "com.my.busname.Processor",
              "EventNotification",
              Glib::ustring(),
              Glib::Variant<std::vector<Glib::VariantBase> >::create_tuple(paramsList));
      }

It seems that the debuger point those line as problematic: Glib::Variant<std::vector<Glib::VariantBase> >::create_tuple(paramsList));

In Glib docs I am unable to find such a member function like create_tuple().

BR,

Krzysztof

klukaspl commented 6 years ago

Hi,

I think I solve my problem by editing the emitSignal function. The generated stub files seem to have hardcoded interface name and signal name (not the one given in xml file).

m_connection->emit_signal(
        m_objectPath,
        "org.freedesktop.DBus.Properties",
        "PropertiesChanged",
        Glib::ustring(),
        propertiesChangedVariant);

After editing them it seems to work fine.

BR,

Krzysztof

jonte commented 6 years ago

Hi Krzysztof,

Did you see the .emit() function for each signal defined in the interface XML?

Signals are intended to be emitted using the sigc::signal interface, which has an emit() function, which in turn is connected to the _emitter function you are using.

The tests illustrate how this is supposed to work, see here for signal emission: https://github.com/Pelagicore/gdbus-codegen-glibmm/blob/master/test/stub/teststubmain.cpp#L315

The automated generation of the sigc::signal signal can be found in the generated _stub.h. Here's a snippet from my locally generated file:

void TestSignalByteStringArray_emitter(std::vector<std::string>); sigc::signal<void, std::vector<std::string> > TestSignalByteStringArray_signal;

So.. In short, please try using TestSignalByteStringArray_signal rather than TestSignalByteStringArray_emitter.

Let me know if this solves your issue - I will make a note of improving documentation around signals!

Thanks for raising the issue!

klukaspl commented 6 years ago

Hi Jonatan, Thank you for the answer. Yes indeed finally I used .emit() function, but to make it work I had to change as well the generated _stub file and the emitSignal () function. The generated emitSignal() seems to have hardcoded interface name and signal name (not the one given in xml file - not the one I need). That part was modified:

m_connection->emit_signal(
        m_objectPath,
        "org.freedesktop.DBus.Properties",
        "PropertiesChanged",
        Glib::ustring(),
        propertiesChangedVariant);

in this manner (adding flexible signalName, change the interface name to the one I need and so on):

bool com::my::dbus::test::emitSignal(const std::string& propName, Glib::VariantBase& value, const Glib::ustring& signalName)
{
    std::map<Glib::ustring, Glib::VariantBase> changedProps;
    std::vector<Glib::ustring> changedPropsNoValue;

    changedProps[propName] = value;

    Glib::Variant<std::map<Glib::ustring,  Glib::VariantBase> > changedPropsVar = Glib::Variant<std::map <Glib::ustring, Glib::VariantBase> >::create (changedProps);
    Glib::Variant<std::vector<Glib::ustring> > changedPropsNoValueVar = Glib::Variant<std::vector<Glib::ustring> >::create(changedPropsNoValue);
    std::vector<Glib::VariantBase> ps;
    ps.push_back(Glib::Variant<Glib::ustring>::create(m_interfaceName));
    ps.push_back(changedPropsVar);
    ps.push_back(changedPropsNoValueVar);
    Glib::VariantContainerBase propertiesChangedVariant = Glib::Variant<std::vector<Glib::VariantBase> >::create_tuple(ps);

    m_connection->emit_signal("/com/my/dbus/test",
                                    "com.my.dbus.test",
                                    signalName,
                                    Glib::ustring(), //to all listeners
                                    propertiesChangedVariant
                                    );
    return true;
}

And after that it finally works fine. Thanks for very nice tool.

BR,

Krzysztof

jonte commented 6 years ago

Hi,

Alright. This does indeed sound like a bug, which needs to be changed in the code generator. I will flag this as such, and we will work on fixing this.

Thanks a lot for the report and the test cases you've supplied.

I will update this issue when the bug has been resolved. If you (or anyone else) happen to have a fix in mind for the code generator, feel free to submit it!

mardy commented 6 years ago

Hi Krzysztof! The emitSignal method is only used in order to emit the PropertiesChanged signal when some object property changes. It's on a standard D-Bus interface, and it's documented here; you should not have to change that.

So, back to your original question, I would need some more information on the crash that you are seeing; can you please paste the backtrace from the debugger?

Also, FYI, the create_tuple method is documented here.

klukaspl commented 6 years ago

Hi Alberto,

OK thanks. In my case I wanted to generate dbus signal not when property is change but on demand - for example when I need to send some value to the client when something happens in my system.

Are the signals only limited to use with properties?

Thanks, Krzysztof

mardy commented 6 years ago

Hi Krzysztof, we definitely want the generator to be able to emit code for emitting generic signals. In the tests, among other things, we are testing that a signal having "s" as signature can be emitted and received, and it seems to be working. So, your use-case should be supported and working, that's why I wanted to see the stack trace to investigate what's going wrong.