2

I have a DLL which is written in Delphi (do not have the source code, but only the API). Here is the DLL function I am trying to invoke through Java using the JNA (version 5.4.0)

DLL Function

The following shows how my Java code looks like.

public interface FPrintDLL extends StdCallLibrary {
    FPrintDLL INSTANCE = Native.load("FPrintDLL", FPrintDLL.class);
    int OPEN_TCPIP(WString ipAddress, int port, int deviceIndex, WString serialKey);
}

public static void main(String[] args) {
    FPrintDLL fPrintDLL = FPrintDLL.INSTANCE;
    WString ipAddress = new WString("192.170.1.3");
    WString serialKey = new WString("12345678");
    int deviceIndex = 4004;
    int port = 9100;

    int connectResult = fPrintDLL.OPEN_TCPIP(ipAddress, port, deviceIndex, serialKey); // Line 81
}

Everything loads fine, the problem is I am getting the following exception,

Exception in thread "main" java.lang.Error: Invalid memory access
at com.sun.jna.Native.invokeInt(Native Method)
at com.sun.jna.Function.invoke(Function.java:426)
at com.sun.jna.Function.invoke(Function.java:361)
at com.sun.jna.Library$Handler.invoke(Library.java:265)
at com.sun.proxy.$Proxy0.OPEN_TCPIP(Unknown Source)
at HelloJNA.main(HelloJNA.java:81)

According to the exception log the problem occurred because of the ints. According to the method signature it doesn't use any pointers/references. So I am not sure what exactly the problem is.

Note - I managed to successfully run this function under the same conditions (the OS, JAVA, DLL architectures are listed below) using the following C# the code,

[DllImport(FPRINT_DLL, CallingConvention = CallingConvention.StdCall)]
public static extern int OPEN_TCPIP([MarshalAs(UnmanagedType.BStr)] string ipAddress,
        int tcpPort,
        int deviceIndex,
        [MarshalAs(UnmanagedType.BStr)] string serialKey);

I mentioned this because to confirm that the given API for OPEN_TCPIP is correct. Now I want to make a direct interaction between Java and the DLL. (not using some kind of a wrapper class)

The DLL is a 32-bit DLL and I am trying it on a 32-bit JVM, Windows10 64bit. FYI I tried the following sources (listed few) but couldn't work this out.

DLL issues and Invalid Memory Access

Java Native Access code Error: “Invalid memory access”

Function call returns java.lang.Error: Invalid memory access

JNA: java.lang.Error: Invalid memory access

Java use JNA call dll error:Invalid memory access (All the required DLLs are in the same directory)

JNA Exception in thread “main” java.lang.Error: Invalid memory access

Does anyone have an idea how to fix this issue?

1
  • 1
    Delphi's WideString is a managed type that is not compatible with non-Delphi compilers. Since you don't have the source code for the DLL, you can't change it to use a different type that is more friendly to Java. That being said, WideString is a wrapper for a COM BSTR, which is why your C# code works. For Java, your only option is to have JNA call Win32 BSTR functions (SysAllocString() and SysFreeString() ) and pass the raw pointers into the DLL. Or else wrap the DLL in another DLL that exposes a more friendly interface for Java. Commented Aug 25, 2019 at 19:18

1 Answer 1

3

The method signature requires a BSTR which requires memory allocation on the C side. You are passing a WString which is causing the Invalid memory access.

Allocate memory for the BSTR arguments like this:

BSTR ipAddress = OleAuto.INSTANCE.SysAllocString("192.170.1.3");
BSTR serialKey = OleAuto.INSTANCE.SysAllocString("12345678");

Once you are finished with the BSTRs you must release the memory:

OleAuto.INSTANCE.SysFreeString(ipAddress);
OleAuto.INSTANCE.SysFreeString(serialKey);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.