【问题标题】:Use C++ DLL from Java with JNA将 Java 中的 C++ DLL 与 JNA 结合使用
【发布时间】:2020-01-31 15:03:24
【问题描述】:

我尝试使用来自 C++ 的 DLL 和 JNA 与来自 Java 程序的 Fanuc 数字控件进行通信,但总是得到这个错误: 线程“主”java.lang.Error 中的异常:内存访问无效

我尝试使用的具体 C++ 方法是 https://www.inventcom.net/fanuc-focas-library/handle/cnc_allclibhndl3

FWLIBAPI short WINAPI cnc_allclibhndl3(const char *ipaddr, unsigned short port, long timeout, unsigned short *FlibHndl);

在 Java 的声明中我使用了这个:

short cnc_allclibhndl3(String ipaddr, short port, NativeLong timeout, short FlibHndl);

我尝试了不同的类型映射,但总是得到相同的错误。

你能告诉我这个声明是否正确吗?

这是我的最后一个节目:

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

public class JnaFanuc {

    public interface Fwlib32 extends Library {
        short cnc_allclibhndl3(String ipaddr, short port, long timeout, short FlibHndl);
    }

    public static void main(String[] args) {
        short p = 0;
        int handle = 0;
        short ret;

        Fwlib32 fwl = (Fwlib32) Native.load("Fwlib32", Fwlib32.class);

        ret = fwl.cnc_allclibhndl3("192.168.1.100", (short)8193, 10, p);

        System.out.println("cnc_allclibhndl3 Ret: " + ret);
        System.out.println("hndl: " + handle);
    }
}

在 Daniel Widdis 回复后编辑。

您好,我尝试了您的解决方案,这是我第一次工作。应用程序以“ret = -16”响应,这意味着“EW_SOCKET (-16) 套接字错误”。这是正常的,因为另一侧没有任何CNC。 当我用真实IP连接真实CNC时出现问题,然后出现与第一次相同的错误。

这是我的实际代码:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.ShortByReference;

public class TestJNA {

    public interface Fwlib32 extends Library {
        Fwlib32 INSTANCE = (Fwlib32) Native.load("Fwlib32", Fwlib32.class);
        short cnc_allclibhndl3(String ipaddr, short port, long timeout, ShortByReference FlibHndl);
}

    public static void main(String[] args) {
        ShortByReference handle = new ShortByReference((short)0);

        short ret = 0;

        Fwlib32 fwl = Fwlib32.INSTANCE;
        ret = fwl.cnc_allclibhndl3("192.168.1.100", (short) 8193, 4, handle);

        System.out.println("cnc_allclibhndl3 Ret: " + ret);
        System.out.println("hndl: " + handle.getValue());
    }
}

这是错误:

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:422)
at com.sun.jna.Function.invoke(Function.java:361)
at com.sun.jna.Library$Handler.invoke(Library.java:265)
at com.sun.proxy.$Proxy0.cnc_allclibhndl3(Unknown Source)
at testjna.TestJNA.main(TestJNA.java:38)

【问题讨论】:

    标签: java c++ dll jna


    【解决方案1】:

    cnc_allclibhndl3() 函数中的最后一个参数是指向short 的指针:

    unsigned short *FlibHndl
    

    所以正确的映射应该是ShortByReference。这将初始化指向内存中其他地方的short 的指针。目前您正在传递一个空 (0) 指针并要求本机方法访问该内存!

    此外,您需要将 C 变量 long 映射到 Java 中的 NativeLong 而不是 long。 Java long 始终为 64 位,但 C long 因操作系统和位数而异。在 Windows 中,这实际上始终是 32 位的,因此如果您的代码仅适用于 Windows,您甚至可以使用 int,但一般/跨平台您应该使用 NativeLong 进行映射。

    此外,约定是将Native.load() 调用作为静态INSTANCE 变量在接口中,而不是像您所做的那样内联定义它。

    试试这个:

    public class JnaFanuc {
    
        public interface Fwlib32 extends Library {
            Fwlib32 INSTANCE = (Fwlib32) Native.load("Fwlib32", Fwlib32.class);
    
            short cnc_allclibhndl3(String ipaddr, short port, NativeLong timeout, short FlibHndl);
        }
    
        public static void main(String[] args) {
            ShortByReference handle = new ShortByReference();
            short ret;
            String ip = "192.168.1.100";
            short port = (short) 8193;
            NativeLong timeout = new NativeLong(10);
            Fwlib32 fwl = Fwlib32.INSTANCE;
    
            ret = fwl.cnc_allclibhndl3(ip, port, timeout, handle);
    
            System.out.println("cnc_allclibhndl3 Ret: " + ret);
            System.out.println("hndl: " + handle.getValue());
        }
    }
    

    【讨论】:

    • 我继续这个问题。你能帮助我吗? (问已编辑)。
    • 你的程序中哪一行是38?
    • 您是否有可能在 64 位系统上使用 32 位 DLL?我看不出映射有什么问题...
    • 这是一个干净的代码。我删除了一些琐碎的行。第 38 行是对 cnc_allclibhndl3 的调用。我在 C# 中有另一个程序,使用相同的库“Fwlib32.dll”和相同的 CNC,并且运行良好。
    • 这就是解决方案。 (将 long 更改为 NativeLong)。现在工作。谢谢!!!!!!
    猜你喜欢
    • 2014-05-06
    • 1970-01-01
    • 2020-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    相关资源
    最近更新 更多