Calling DYLIB callbacks to Xojo app

  1. 7 months ago

    Garth H

    1 Nov 2019 Testers, Xojo Pro

    FINALLY - I am moving to the latest Xojo, working in macOS 10.14 Mojave, after using RealStudio 2011r3 for the past 8 years (which has been very successful for me). I find that I have to do very little to get it to work, mostly fixing my threading cheating (altering UI elements in a thread).

    In that light, there is one major violation (I think) which doesn't throw any exceptions, and you'll see why. I'd like to know what would be the best fundamental way to refactor this. It's a pretty simple question; I'm just making it sound complicated.

    I use REAL/Xojo mostly to serve as a front end, although I do plenty within it. But most of the work of my app(s) is in a DYLIB/DLL, which does long operations and calls a callback function in my REAL/XOjo UI app to display progress.

    This is the process I use, and it works great on Mac and Windows, using 2011r3, but I very much suspect it does not - causes hard crashes - in Xojo.

    Function FakeWorkFunc() As Integer
       // not called within a thread 
       Soft Declare Function DoConvert Lib "conversionengine.dylib" (Inst1 As Integer, Inst2 As Integer) As Integer
       Dim Param1, Param2 As Integer
       Dim ErrCode As Integer
       // function takes say 10 minutes. It calls the Xojo-contained callback function (it has the address)
       ErrCode = DoConvert(Param1, Param2)
       return ErrCode
    End Function
    Function ProgressCallback(Buff As Ptr) As Integer
       // decodes Buff into a MemoryBlock and essentially gets a string and float out of it
       // never mind how
       Dim ProgressText As String
       Dim ProgressAmt As Single
       frmProgress.txtProgress.Text = ProgressText
       frmProgress.ProgresBar1.Value = ProgressAmt * 1000
       return 1
    End Function

    I think obviously the DYLIB/DLL banging on the UI thread while it's still held up with the called function, is NOT GOOD.

    And, additionally, I have some Xojo-based functions which the DYLIB/DLL calls - not UI related - where it gets some work done.

    So, smart people everywhere, how would you refactor this so it wold play ball with the more thread-safe nature of the latest Xojo?

  2. Andrew L

    1 Nov 2019 San Francisco, CA, USA
    Edited 7 months ago

    I would move the UI-related code from the callback into a Timer, and have the callback trigger the timer. The Timer's action event is guaranteed to run on the main/UI thread.

    Function ProgressCallback(Buff As Ptr) As Integer
       // decodes Buff into a MemoryBlock and essentially gets a string and float out of it
       // never mind how
    // convert these variables to properties accessible to both the callback and the timer
       Dim ProgressText As String 
       Dim ProgressAmt As Single
       myTimer.Mode = Timer.ModeSingle
       App.YieldToNextThread() // so the main thread can run
       return 1
    End Function
  3. Javier M

    2 Nov 2019 Xojo Inc, Testers, Xojo Pro, XDC Speakers, Third Party Store AprendeXojo - Europe, Spain

    Hi @Garth H

    Would you use the new Thread.UserInterfaceUpdate available since 2019r2?


  4. Ulrich B

    2 Nov 2019 Testers, Xojo Pro Europe (Germany, Berlin) · xo...

    If the callback is triggered from a background thread (which is not officially supported), you have to take some precautions:
    Use pragmas to disable backgroundtasks and Stackoverflow checks.
    Do not access instances or their properties and don‘t create them.
    And of course don‘t access the GUI.

  5. Garth H

    4 Nov 2019 Testers, Xojo Pro

    (First a note: where did I say anywhere that I was using Threads?)

    OK, thank you Andrew Lambert, what you said made sense, but... it doesn't work. And I think why is because (I don't think) I'm not violating anything in the first place. Maybe everything I'm doing occurs in the same, main thread. So this was kind of a trick question?

    This is all a serial operation, if you consider that the dylib is simply an extension of the Xojo app. And it is, right? It all shares the same process space. Every one of these operations are synchronous, they don't continue until they are individually finished.

    App pulls up a dialog
    User inputs some parameters
    Clicks OK
    The button handler calls a Xojo function
    The function calls a dylib function
    The dylib does some stuff, at times calls back to to Xojo app
    The Xojo app modifies the UI, and returns control back to the dylib
    The dylib finishes up what it was doing and the function that was call returns control to Xojo
    Xojo shuts down the progress window and throws up a MsgBox finished prompt

    So perhaps I'm not doing anything wrong in the first place?

  6. Norman P

    4 Nov 2019 Testers, Xojo Pro outside LMAO !!!!!!!

    that would really depend on how the dylib code is doing what it does
    if its not multi threaded in and of itself then it _shouldn't_ be an issue
    but if it is then IF you could get a callback on a non-main thread then andrew advice to set a property and start a timer may prevent issues (there are precious few thigns you can do from an async callback - setting a property that is a simple type is one)
    however you may have needed to start the timer before starting the call to the dylib as one thing you should not do from an async callback is call any Xojo code beyond setting a simply property

    that doesnt _seem_ to be the issue here but without more detail about how the dylib operates its hard to give specific advice

    is it possible that the dylib links against something that does spawn a thread ?

  7. Garth H

    4 Nov 2019 Testers, Xojo Pro

    All purely functional, no spawning nothing, no threads, no timers. I'm just surprised that I can click on the button on my dialog. But it all works, just like it did on 2011r3 in OSX 10.6.

  8. Norman P

    4 Nov 2019 Testers, Xojo Pro outside LMAO !!!!!!!
    Edited 7 months ago

    you were expecting it to NOT work ?
    there's no reason it should fail I can think of if its as straight forward as you say
    if the call to the dylib is entirely synchronous then xojo basically waits until that call returns like always
    no reason that would just randomly change

or Sign Up to reply!