Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with signal sending. #9

Open
klukaspl opened this issue Apr 19, 2018 · 7 comments
Open

Problem with signal sending. #9

klukaspl opened this issue Apr 19, 2018 · 7 comments
Assignees
Labels
bug Something isn't working

Comments

@klukaspl
Copy link

klukaspl commented Apr 19, 2018

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
Copy link
Author

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 jonte self-assigned this Apr 26, 2018
@jonte
Copy link
Contributor

jonte commented Apr 26, 2018

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
Copy link
Author

klukaspl commented Apr 26, 2018

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
Copy link
Contributor

jonte commented Apr 26, 2018

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!

@jonte jonte added the bug Something isn't working label Apr 26, 2018
@mardy
Copy link
Contributor

mardy commented Apr 27, 2018

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
Copy link
Author

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
Copy link
Contributor

mardy commented Apr 27, 2018

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants