Errors calling function from DLL

420 views
Skip to first unread message

Jason H

unread,
Jul 26, 2011, 10:48:15 AM7/26/11
to Java Native Access
Hello all,

I am writing a plugin for a program in java and part of the plugin has
to control a motor hooked up to the pc. The manufacturer has provided
a prebuilt DLL that contains all the functions to run this motor (I
have no access to the source code for the library). They have also
provided a list of all the functions in the DLL. The DLL is called
"PerformaxCom.dll"

Here are 2 of the functions I want to use, as referenced by a) Product
documentation, b)dependency walker, c) header file.

Product Documentation:
BOOL fnPerformaxComGetNumDevices(OUT LPDWORD lpNumDevices);
BOOL fnPerformaxComOpen(IN DWORD dwDeviceNum, OUT HANDLE* pHandle);

Dependency Walker:
_fnPerformaxComGetNumDevices@4
_fnPerformaxComOpen@8

Header File:
extern "C" __declspec(dllimport) BOOL _stdcall
fnPerformaxComGetNumDevices(OUT LPDWORD lpNumDevices);
extern "C" __declspec(dllimport) BOOL _stdcall fnPerformaxComOpen(IN
DWORD dwDeviceNum, OUT HANDLE* pHandle);


Now below I have posted my initial attempts to call these functions
via JNA (actually, in my example below I have only attempted to call 1
of the functions). Below the code, I have posted the error messages
generated.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
package javaapplication1;

import com.sun.jna.*;
import com.sun.jna.win32.*;


public class JavaApplication1 {

public interface PerformaxCom extends StdCallLibrary {
public int fnPerformaxComGetNumDevices();

}

public static void main(String[] args) {
PerformaxCom controller = (PerformaxCom)
Native.loadLibrary("PerformaxCom", PerformaxCom.class);
int a;
a = controller.fnPerformaxComGetNumDevices();
System.out.print(a);

}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error
looking up function 'fnPerformaxComGetNumDevices': The specified
procedure could not be found.

at com.sun.jna.Function.<init>(Function.java:179)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:347)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:327)
at com.sun.jna.Library$Handler.invoke(Library.java:203)
at $Proxy0.fnPerformaxComGetNumDevices(Unknown Source)
at javaapplication1.JavaApplication1.main(JavaApplication1.java:17)
Java Result: 1

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

I believe, from all my research on the issue up to this point, that I
am going to have to "map" the function names? I understand the basic
concept but am clueless on how to code it. I do not know the commands
or format to use in carrying out this process. Can anyone teach me how
to achieve accessing these functions?


Thank you,

Jason H

Daniel Doubrovkine

unread,
Jul 26, 2011, 10:57:20 AM7/26/11
to jna-...@googlegroups.com
BOOL fnPerformaxComGetNumDevices(OUT LPDWORD lpNumDevices);
BOOL fnPerformaxComOpen(IN DWORD dwDeviceNum, OUT HANDLE* pHandle);

Both return something (number of devices and a handle)

Try these:

boolean fnPerformaxComGetNumDevices(DWORDByReference lpNumDevices)
boolean fnPerformaxComGetNumDevices(DWORD dwDeviceNum, HANDLEByReference pHandle)

Jason H

unread,
Jul 26, 2011, 12:45:20 PM7/26/11
to Java Native Access
Thank you for the reply. The "DWORDByReference" is showing up as an
error...: Exception in thread "main" java.lang.NoClassDefFoundError:
DWORDByReference

Do I need to import something else?
> dblock.org <http://www.dblock.org> -
> @dblockdotorg<http://twitter.com/#!/dblockdotorg>

Daniel Doubrovkine

unread,
Jul 26, 2011, 3:46:37 PM7/26/11
to jna-...@googlegroups.com
Use an IntByReference for now.

dblock.org - @dblockdotorg


Jason H

unread,
Jul 26, 2011, 4:26:36 PM7/26/11
to Java Native Access
Thank you! That gets the code running!

This may be a stupid question, but how can I get the output (ie the
number of devices it finds)?

Daniel Doubrovkine

unread,
Jul 27, 2011, 8:08:24 AM7/27/11
to jna-...@googlegroups.com
The ByReference class has a method, getValue().

Now that you know all this, fork JNA and make a pull request that documents this better in, maybe https://github.com/twall/jna/blob/master/www/ByRefArguments.md.

Thanks,
dB.

Jason H

unread,
Jul 27, 2011, 8:19:19 AM7/27/11
to Java Native Access
So I did something idiotic: when I tested my code, i had the actual
function call commented out. /forehead-smack.

Actually calling the function results in:

Exception in thread "main" java.lang.UnsatisfiedLinkError: Error
looking up function 'fnPerformaxComGetNumDevices': The specified
procedure could not be found.

allocated@0x30727d8 (4 bytes) at
com.sun.jna.Function.<init>(Function.java:179)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:347)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:327)
at com.sun.jna.Library$Handler.invoke(Library.java:203)
at $Proxy0.fnPerformaxComGetNumDevices(Unknown Source)
at javaapplication1.JavaApplication1.main(JavaApplication1.java:21)
Java Result: 1

What am I missing?



On Jul 27, 8:08 am, Daniel Doubrovkine <dbl...@dblock.org> wrote:
> The ByReference class has a method, getValue().
>
> Now that you know all this, fork JNA and make a pull request that documents
> this better in, maybehttps://github.com/twall/jna/blob/master/www/ByRefArguments.md.

Timothy Wall

unread,
Jul 27, 2011, 8:38:05 AM7/27/11
to jna-...@googlegroups.com
Run "depends.exe" on your dll to find the actual name of the function.

If it ends in @NNN, then you're using the stdcall calling convention and need to ensure that the corresponding function mapper is used.

Jason H

unread,
Jul 27, 2011, 8:51:51 AM7/27/11
to Java Native Access
the function in depends.exe is shown as
"_fnPerformaxComGetNumDevices@4"

In my code I am already extending StdCallLibrary, and I am now calling
_fnPerformaxComGetNumDevices

It still doesn't run. How do I set up to map the function? I don't
know how to do it at all.

Thanks,

Jason H

Timothy Wall

unread,
Jul 27, 2011, 9:46:44 AM7/27/11
to jna-...@googlegroups.com
StdCallLibrary indicates the calling convention. Since not all stdcall libraries have decorated names (the w32 apis do not), you have to explicitly supply the function mapper when required.

There is a StdCallFunctionMapper provided for this purpose; provide it in the library options map when you initialize your library (second argument to Native.loadLibrary()).

Feel free to fork, improve the docs, and push changes.

Jason H

unread,
Jul 28, 2011, 9:19:03 AM7/28/11
to Java Native Access
Ok, I have tried off and on all day yesterday to craft something to
accomplish this mapping and I cannot do it. I don't even know what the
code should look like, or where it should go. I'm just spitting out
random sequences of code in hopes of stumbling into the solution. I
want to learn how to map a function name from a simple java method to
a mangled function name in the DLL.

How to I "explicitly supply the function mapper"? some sample code
would be incredible.

_jason Haynes

Jason H

unread,
Jul 28, 2011, 9:19:56 AM7/28/11
to Java Native Access
And as soon as I understand this process, I will write up some
documentation to explain it in the future to people like myself who
walk into this with little to no knowledge of the topic.

Timothy Wall

unread,
Jul 28, 2011, 12:14:48 PM7/28/11
to jna-...@googlegroups.com
This used to exist in at least two locations in the javadoc, and I could have sworn it was in the main docs as well, but things are easily lost when transitioning from one location to another.

Map options = new HashMap();
options.put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper());
Native.loadLibrary("mylib", options);

If the javadoc is not directly available on githup, it was an oversight on our part. However, it's trivial to regenerate from the source, and it's included (or should be) in the download. A large part of JNA's documentation rests within the javadoc; you can learn by browsing.

Daniel Doubrovkine

unread,
Aug 5, 2011, 8:33:17 AM8/5/11
to jna-...@googlegroups.com
I'm taking a look at publishing javadocs to github.

dblock.org - @dblockdotorg


Reply all
Reply to author
Forward
0 new messages