Closed richard-ramos closed 4 years ago
Can you explain your use case?
Sure!
TLDR: I want to invoke a QObject slot proc from a non-qt thread
We are currently working on a desktop client for status.im, with nim+NimQML for the frontend, and a go library exported as a static library for the backend. This library has a function that receives a callback. It also has an event loop where this callback is executed, passing as arguments json strings (we call them 'signals'). On this callback is where we receive the chat messages.
For reference, here's the binding used for that function:
type SignalCallback* = proc(eventMessage: cstring): void {.cdecl.}
proc setSignalEventCallback*(callback: SignalCallback) {.importc: "SetSignalEventCallback".}
Originally I attempted to call the slot function of a QObject directly inside the callback I pass to setSignalEventCallback
, but I ended up with some SIGSEGV: Illegal storage access. (Attempt to read from nil?)
. So, after some research, I found out that since the callback is executed in a non-qt thread, invokeMethod
seemed like the way to go to achieve cross-event-loop communication, and I ended up adding a new function in DOtherside and NimQML:
https://github.com/status-im/dotherside/blob/master/lib/src/DOtherSide.cpp#L721-L725
https://github.com/status-im/nimqml/blob/master/src/nimqml.nim#L33-L36
This function is then invoked here and we end up receiven the signals successfully. https://github.com/status-im/nim-status-client/blob/5ca1cfbe198272bb97e5a501f76272941c9c7461/src/nim_status_client.nim#L85-L88
Of course, this is still a WIP. I want to create a cpp library where this dos_signal will live, and a nim package for the nim->c bindings instead of adding these functions inside DOtherSide and NimQML. (I'm still struggling in how to do that due to lack of experience in both C++ and Nim).
Another thing I want to improve is removing the need of having the QObject as a global variable like I do here: https://github.com/status-im/nim-status-client/blob/signal-handling/src/nim_status_client.nim#L27-L29 because having the callback being declared with the {.cdecl.}
pragma causes nim to complain: illegal capture 'logicQObjPointer' because ':anonymous' has the calling convention: <cdecl>
Oops! I opened this PR by mistake