Per lo spessore dell'argomento in sé da un punto di vista puramente teorico, vorrei riportare quanto da me sperimentato e la discussione sorta nella Mailing List internazionale, circa il mancato funzionamento di una "
funzione Callback" in Gambas.
Dunque, l'intento era quello di
trasportare da C a Gambas un semplice
codice per creare un
Client del
Server audio:
Jack.
Il
codice prevedeva la chiamata di una
funzione Callback, che ho provveduto a scrivere in Gambas come previsto dalla
documentazione ufficiale al riguardo.
Lanciato il mio applicativo, però, notavo che la
funzione Callback non funzionava, ed anzi l'applicativo andava in grave errore 11:
Segmentation fault.
Dopo vari tentativi e modifiche, ho esposto la questione a Minisini nella
Mailing List ufficiale di
Gambas.
La questione, piano piano, ha suscitato un certo interesse, data la particolarità dell'argomento, e ne riporto in ordine temporale gli interventi più interessanti:
«
Sorry, I don't know the least what this project is about but the comment in
the C sources state that the callback is executed in a "special realtime
thread". This is the same problem as here:
http://sourceforge.net/mailarchive/message.php?msg_id=30895071
I suspect.
Regards,
Tobi »
«
Problem may be here:sizeof (jack_default_audio_sample_t) * nframes);
memcpy(outp, inp, SizeOf(gb.Float) * nframes)
Is it really float, instead of single (in C float and double)?
Jussi »
Minisini mi comunica di essere riuscito a non ottenere l'errore di tipo 11:
«
I can run your program with no crash if:
1) I rewrite the code at line 62.Dim status As Integer
client = jack_client_open(nomeClient, JackNullOption, VarPtr(status), Null)
(the status argument must be a pointer to a 'jack_status_t' that should
be an 'int')
2) I run the code from a module and not from a form. In other words,
outside of the QT4 GUI loop that does not like threads.
If you want to generate useful backtrace, you have to compile Gambas
with debugging information enabled.
Otherwise, you can use 'valgrind' to detect illegal memory accesses when
they occur. But 'valgrind' is not fond of threads too!
Regards,
--
Benoît Minisini »
«
I think Benoit is right about Integer.
http://en.wikipedia.org/wiki/Word_%28computer_architecture%29
In MS way (the wrong way) it was; word (16bit), dword (32bit) and qword (64bit).
Jussi »
Minisini, ad ogni modo, conferma l'impossibilità di far funzionare il mio applicativo, per le medesime ragioni esposte dall'utente
Tobias (vedi sopra il primo intervento):
«
Anyway, don't expect your callback to work, as it is run in another
thread, and the Gambas interpreter cannot be run outside of the main thread.
Regards,
--
Benoît Minisini[/i] »
«
So.... we can make any changes and corrections we want, but it will never work?
vuott »
Minisini, però, indica teoricamente una possibilità:
«
If the callback run in another thread, yes.
--
Benoît Minisini »
«
Can this be fixed by using Task?
Jussi »
«
I don't see how. Task is a child process, this has nothing to do with
our problem: calling the Gambas interpreter inside a thread, which is
not possible because the Gambas interpreter is not multi-threaded.
--
Benoît Minisini »
Bene, ricordando l'indicazione di Minisini, io provo a spostare la chiamata della funzione
Callback e la stessa
funzione Callback in un'apposita
libreria condivisa .so, scritta in linguaggio C e creata da me, cercando in questo modo di tenere
separati il codice Gambas (che raccoglie la gran parte del codice C trasportato in Gambas) e il restante codice C della
funzione Callback in questione.
La mia intuizione
ha successo (...anche se mi pare una
furbata ) ! Lo comunico, quindi, alla M.L.I.:
«
Hello,
well, I have been able to run the application, but..... using a shared library .so written by me.
I moved the call to "callback" function and the same "callback" function in that shared library.
Excuse me: I am so ashamed for the tricksy !
vuott »
Il mio risultato suscita interesse ed... anche qualche complimento:
«
Nice workaround!
However I don't quite understand why it works (I think the library is in
same thread than gbx3).
Jussi »
«
It works because the callback is written in C, it does not run the
Gambas interpreter.
--
Benoît Minisini »
«
Well obviously. Didn't really answer the question.
I guess the answer is that shared libraries can be run in different thread,
even if their callers can't.
Jussi »
«
It does. The interpreter cannot be run *from* a different thread. A
callback written in C can. Being in a shared library or not changes nothing there.
--
Benoît Minisini »