3

I am new in Java, searched for this question in google and stackoverflow, found some posts, but still I can't understand.

I want to use DLL libary (C++) methods from Java. I use JNA for this purpose. JNA found my library but it can't find my method: Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'LoadCurrentData': The specified procedure could not be found.

My code:

package javaapplication1;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Pointer;

public class JavaApplication1 {

    public interface LibPro extends Library {
        LibPro INSTANCE = (LibPro) Native.loadLibrary(
            (Platform.isWindows() ? "LibPro" : "LibProLinuxPort"), LibPro.class);

        public  short LoadCurrentData();
    }

    public static void main(String[] args) {
      LibPro sdll = LibPro.INSTANCE;
      sdll.LoadCurrentData();  // call of void function
    }
 }

I looked in my DLL with Depency Walker Tool and saw that my function name has prefix and suffix - it looks like _LoadCurrentData@0

Thanks for response!

P.S. I found good example which works http://tutortutor.ca/cgi-bin/makepage.cgi?/articles/rjna (Listing 6).

Darkwing
  • 314
  • 9
  • 24
  • What does LibPro do? There might be a (really quick) pure java way to achieve this without having to delve into the nightmarish native library implementation. – Will Jan 13 '13 at 14:48
  • Without LibPro I have to deal with nightmarish byte data parsing and crc checks. – Darkwing Jan 13 '13 at 14:59

1 Answers1

3

I'd say that you need to apply correct name mapper, as you noticed function name got mangled, you need to register CallMapper that will implement the same mangling as your compiler.

Here is a revelant entry from JNA homepage:

Use a dump utility to examine the names of your exported functions to make sure they match (nm on linux, depends on Windows). On Windows, if the functions have a suffix of the form "@NN", you need to pass a StdCallFunctionMapper as an option when initializing your library interface. In general, you can use a function mapper (FunctionMapper) to change the name of the looked-up method, or an invocation mapper (InvocationMapper) for more extensive control over the method invocation.

Here is a possibly revelant question: renaming DLL functions in JNA using StdCallFunctionMapper

Community
  • 1
  • 1
jb.
  • 23,300
  • 18
  • 98
  • 136
  • In addition, you need to extend `StdCallLibrary` (instead of `Library`) on Windows, or conditionally pass in `Library.OPTION_CALLING_CONVENTION` with a value of `StdCallLibrary.STDCALL_CONVENTION` when loading on Windows. – technomage Jan 13 '13 at 15:18
  • Why it doesn't work if i call method with necessary suffix `_LoadCurrentData()`? – Darkwing Jan 13 '13 at 15:19
  • Because mangled function name is `_LoadCurrentData@0` (notice the `@0`), and function name containing `@` is illegal in Java. – jb. Jan 13 '13 at 15:27
  • @technomage Thanks for the tip! Helped a lot. In my case, I didn't even have to write code to distinguish between Windows and other platforms - JNA 4.5.1 with the `StdCallLibrary.FUNCTION_MAPPER` option seems to work on Windows 7 32-bit, Mac OS 10.13.2, Unbuntu Linux 16.04 64-bit. (I didn't try the `StdCallLibrary.STDCALL_CONVENTION`.) See my answer here: https://stackoverflow.com/questions/5156055/jna-the-specified-procedure-could-not-be-found/48443321 – jcsahnwaldt Reinstate Monica Jan 25 '18 at 13:02