How can I call the GLib threads g_thread_init using JNA?
I'm trying to invoke a function in a native C library using JNA which uses GLib and GLib Threads. When I attempt to invoke the function, the JVM crashes and the following error is printed:
GLib-ERROR **: The thread system is not yet initialized.
aborting...
I'm pretty sure that means the code needs to invoke the g_thread_init
function in the gthread
library before invoking the target function. Thus, I defined the following interface to load the gthread
library...
public interface GLibThreads extends Library {
public static final GLibThreads INSTANCE =
(GLibThreads) Native.loadLibrary("gthread-2.0", GLibThreads.class);
public void g_thread_init(Pointer pointer);
}
...and I tried invoking it before the target function...
NativeLibrary.getInstance("glib-2.0");
GLibThreads.INSTANCE.g_thread_init(Pointer.NULL);
String flavors = LibSoda.INSTANCE.getFlavors();
...but unfortunately, this doesn't work. I开发者_StackOverflow社区 still get the "thread system is not yet initialized" error.
I thought my problem might have been related to defining the method to take a JNA Pointer
. Here's how the g_thread_init
function is defined in the gthread header:
void g_thread_init (GThreadFunctions *vtable);
So I tried defining the GThreadFunctions
struct and passing in null
. Unfortunately, that didn't make any difference, and I still get the "thread system is not yet initialized" error.
How can I initialize the threading system so I can successfully invoke the target function?
Don't load the glib library before calling g_thread_init.
NativeLibrary.getInstance("glib-2.0") explicitly loads glib. While calling g_thread_init eventually implicitly loads glib (depending on the OS's own dependency tracking), it probably does so after setting up whatever parts of gthread that trigger the error if not set up.
Don't load the glib library before calling g_thread_init.
When I removed the NativeLibrary.getInstance("glib-2.0");
line of code, the thread system initialized and the call to the LibSoda.INSTANCE.getFlavors()
succeeded!
I'm not entirely sure why this worked. I know accessing the gthread-2.0
library will implicitly load GLib, but I don't know why loading GLib explicitly first causes the g_thread_init
call to be ignored.
I'll gladly change which answer is accepted to an answer which explains why the above worked.
精彩评论