Using JNA with asynchronous callbacks

1,142 views
Skip to first unread message

Alisson Sales

unread,
Jul 26, 2011, 5:03:23 PM7/26/11
to Java Native Access
Hi guys, I'm trying to usa a C library with JNA, some functions works
fine, but this library has some callbacks that are called
asynchronously. Is it possible to do this?

Here is an example what I'm trying.

https://gist.github.com/7a91a22856b716145caf

This should print the callbacks arguments after connect.

Am I doing something wrong?

Thanks




Timothy Wall

unread,
Jul 27, 2011, 6:29:35 AM7/27/11
to jna-...@googlegroups.com
Callbacks are called in an appropriate Java thread context, even if spawned from a native thread.

N.D. Khanh Do

unread,
Feb 11, 2014, 3:24:16 PM2/11/14
to jna-...@googlegroups.com
Hi everyone,

I'm get stucked in the same situation when using JNA to pass a callback function to a DLL, and expect this callback function will be called asynchronously from the DLL. Unfortunately, it doesn't work.

For more detail, I'm using JNA to work with a DLL developed in Delphi. I pass a Java callback function to the DLL's function and expect this callback function will be called back by the DLL asynchronously.

The problem is the callback function can be called back synchronously only (while calling the DLL function from JNA), but it's never called back when the dll wants to call it asynchronously.

Could you please help to let me know how to do asynchronous callback in JNA?

Thanks in advance!

Khanh Do

N.D. Khanh Do

unread,
Feb 12, 2014, 5:47:48 AM2/12/14
to jna-...@googlegroups.com
After doing some debugs, I also realize that after the JNA calling function is finished, the dll is detached from the VM, this causes the dll has no chance to do callback afterwards.

So is there any method to keep the dll still be attached to the VM after the calling function is finished?

Thank you.
Khanh Do

Timothy Wall

unread,
Feb 12, 2014, 7:34:06 AM2/12/14
to jna-...@googlegroups.com
What indicates that the DLL is “detached”, and what exactly does that mean?

JNA will load the DLL, and generally keep it in loaded until any Java reference to it (NativeLibrary) is garbage-collected.
> --
> You received this message because you are subscribed to the Google Groups "Java Native Access" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jna-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/groups/opt_out.

N.D. Khanh Do

unread,
Feb 13, 2014, 6:02:09 AM2/13/14
to jna-...@googlegroups.com
Hi Timothy Wall,

Thank you very much for your response. 

While tracking the DLL debug messages, "detached" here is an event which dll throws when the DLL is detached from the DLL caller, i.e. JNA.

My situation is: 
   
I pass a callback function to the DLL by calling a JNA_DLL.PassCallBackFunction inside the functionA.

While functionA is not finished, the DLL can fire the callback function (like Code 1). But when the functionA is finished, the DLL cannot fire this callback function anymore. Doing dll debug, I got "dll detached" message as mentioned.

//------Code 1--------
void functionA {
    JNA_DLL.PassCallBackFunction(callback);
...
}
//-----------------------

I just found a solution by putting the JNA_DLL.PassCallBackFunction(callback) inside a thread with some "magic code" (like Code 2). Afterwards, the callback is always called back from the DLL.

//------Code 2---------
void functionA {
   Thread keepAlive = new Thread(new Runnable() {
            @Override
            public void run() {
        JNA_DLL.PassCallBackFunction(callback);        
        WinUser.MSG msg = new WinUser.MSG();
        while (((User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0)) {
        User32.INSTANCE.TranslateMessage(msg);
        User32.INSTANCE.DispatchMessage(msg);
        }
    }
   keepAlive.start();  
...
}
//-----------------------

I know this is only a work-around including some "magic" code (I got somewhere in internet) in blue, which I has no idea about them. But it works.

Could you give me a better solution to use JNA in my case?

Thanks in advance
Khanh Do

Timothy Wall

unread,
Feb 13, 2014, 7:06:18 AM2/13/14
to jna-...@googlegroups.com
What in the world encouraged you to include that particular “magic” code? Basically you’re establishing a windows message/event pump, which apparently your DLL requires in order for it to continue to operate.

Apparently it’s your DLL that’s doing the detaching, not JNA.

N.D. Khanh Do

unread,
Feb 13, 2014, 8:00:29 AM2/13/14
to jna-...@googlegroups.com
Thank you for your quick and clear answer.

Regarding to the mentioned code, to establish the message/event connection between the JNA and my DLL:

WinUser.MSG msg = new WinUser.MSG();
while (((User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0)) {
User32.INSTANCE.TranslateMessage(msg);
User32.INSTANCE.DispatchMessage(msg);
}

This code works fine in Java desktop application. But when I apply it to my Java web application (running in Glassfish 4), I got an error  at the line: 

WinUser.MSG msg = new WinUser.MSG();

as following:

SEVERE:   Exception in thread "Thread-41"
SEVERE:   java.lang.NoSuchMethodError: com.sun.jna.IntegerType.<init>(IJZ)V
at com.sun.jna.platform.win32.WinDef$UINT_PTR.<init>(WinDef.java:301)
at com.sun.jna.platform.win32.WinDef$WPARAM.<init>(WinDef.java:318)
at com.sun.jna.platform.win32.WinDef$WPARAM.<init>(WinDef.java:314)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
at com.sun.jna.NativeMappedConverter.defaultValue(NativeMappedConverter.java:47)
at com.sun.jna.NativeMappedConverter.<init>(NativeMappedConverter.java:41)
at com.sun.jna.NativeMappedConverter.getInstance(NativeMappedConverter.java:29)
at com.sun.jna.Structure.calculateSize(Structure.java:717)
at com.sun.jna.Structure.allocateMemory(Structure.java:251)
at com.sun.jna.Structure.<init>(Structure.java:153)
at com.sun.jna.Structure.<init>(Structure.java:143)
at com.sun.jna.Structure.<init>(Structure.java:139)
at com.sun.jna.Structure.<init>(Structure.java:130)
at com.sun.jna.platform.win32.WinUser$MSG.<init>(WinUser.java:130)

I am using the JNA "jna-4.0.0.jar" and "platform-3.5.2.jar".

If possible, could you please let me know why I got this error?

Thank you so much.
Khanh Do

N.D. Khanh Do

unread,
Feb 13, 2014, 8:52:35 AM2/13/14
to jna-...@googlegroups.com
The problem is solved with the older platform-3.4.0 version. All platform versions newer than 3.4.0 are affected by this error.

Thank you.

Kustaa Nyholm

unread,
Feb 13, 2014, 8:56:50 AM2/13/14
to jna-...@googlegroups.com

> The problem is solved with the older platform-3.4.0 version. All platform versions newer than 3.4.0 are affected by this error.

I would not call this solved, rather circumvented, postponed or wiped under the carpet.

This is either a problem in your code, the DLL you are calling or JNA newer than 3.4.0,;
unless you find out the real problem this is going to come back and byte someone's
backside...either yours or some other JNA users. 

So it would be great if you persisted and found out the actual trouble and
reported back here.

br Kusti




This e-mail may contain confidential or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. We will not be liable for direct, indirect, special or consequential damages arising from alteration of the contents of this message by a third party or as a result of any virus being passed on or as of transmission of this e-mail in general.

N.D. Khanh Do

unread,
Feb 13, 2014, 9:00:21 AM2/13/14
to jna-...@googlegroups.com
OK, thank you Kusti.

Neil C Smith

unread,
Feb 13, 2014, 9:11:12 AM2/13/14
to jna-users
Hi,

On 13 February 2014 12:06, Timothy Wall <twal...@java.net> wrote:
> What in the world encouraged you to include that particular "magic" code? Basically you're establishing a windows message/event pump, which apparently your DLL requires in order for it to continue to operate.

Couldn't this still be your original suggestion too, that this is down
to garbage collection? Depending on the rest of the code, that
infinite loop could be keeping a reference to the native library
alive?

Be interesting to know if it's still "fixed" if that loop is replace
with while (true) {Thread.sleep(...) }

Best wishes,

Neil

--
Neil C Smith
Artist : Technologist : Adviser
http://neilcsmith.net

Praxis LIVE - open-source intermedia development - www.praxislive.org
Digital Prisoners - interactive spaces and projections -
www.digitalprisoners.co.uk
OpenEye - the web, managed - www.openeye.info
Message has been deleted

N.D. Khanh Do

unread,
Feb 13, 2014, 10:33:41 AM2/13/14
to jna-...@googlegroups.com
Hi Neil,

Thanks for you suggestion. But the callback cannot be called back, after replacing the existing code: 
WinUser.MSG msg = new WinUser.MSG();
while (((User32.INSTANCE.GetMessage(msg, null, 0, 0)) != 0)) {
User32.INSTANCE.TranslateMessage(msg);
User32.INSTANCE.DispatchMessage(msg);
}

by your suggestion code:

while (!stop) {
Thread.sleep(3000);
}

It seems a existing code is a must to remain the communication between the DLL and JNA.

Thanks
Khanh Do
Reply all
Reply to author
Forward
0 new messages