Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JNA访问DLL:输出不符合预期顺序_Java_Dll_Jna - Fatal编程技术网

Java 使用JNA访问DLL:输出不符合预期顺序

Java 使用JNA访问DLL:输出不符合预期顺序,java,dll,jna,Java,Dll,Jna,背景第一,问题以粗体显示: 我是一名学生,为了一个暑期研究项目,我将编写一个Java程序,让我在Windows环境下将从研究硬件收集的数据导出到MATLAB——我不需要该程序可移植到其他平台。我有一个第三方DLL,它有一个很棒的API,其中包含C/C++声明,但是我没有访问DLL源代码的权限 我只知道Java,所以在查看了可用的选项之后,我决定使用JNA,因为它看起来最简单、最直接,而且JNA目前是维护的。我问一个知道C++的朋友给我做了一个例子DLL,所以我可以从底部开始做一个“Hello W

背景第一,问题以粗体显示:

我是一名学生,为了一个暑期研究项目,我将编写一个Java程序,让我在Windows环境下将从研究硬件收集的数据导出到MATLAB——我不需要该程序可移植到其他平台。我有一个第三方DLL,它有一个很棒的API,其中包含C/C++声明,但是我没有访问DLL源代码的权限

我只知道Java,所以在查看了可用的选项之后,我决定使用JNA,因为它看起来最简单、最直接,而且JNA目前是维护的。我问一个知道C++的朋友给我做了一个例子DLL,所以我可以从底部开始做一个“Hello World”风格的测试,加载库并使用JNA访问本机方法。我遵循了来自的例子,阅读了twall和/或technomage对其他人问题的大约一百条回复

在解决了由于jna.library.path以null开头而导致的一些不满意的链接错误后,我将提供给我的32位示例DLL重新编译为64位,并将它们都放入/bin文件夹中,然后让程序根据JVM的运行情况确定要访问哪一个。我知道我不能用我的第三方DLL(32位)来实现这一点,但这只是我概念验证阶段的一部分

我已经能够很容易地访问DLL方法,但我看到输出——所有打印语句——的顺序出乎意料。看起来我的Java代码从头到尾执行,然后本机库从头到尾执行

在我的项目后面,我将需要调用本机函数,然后调用java方法,然后再次调用本机函数,所以我需要在早期理解是什么导致了这个奇怪的序列。起初我尝试了一种非常程序化的方法;下面是我将这些方法装扮成我可以操作的对象的尝试,得到了相同的结果。我猜想这与JVM和本机的交互方式有关,或者与windows和Java处理I/O的方式不同有关,但是我很难理解是什么导致了它,或者如何解决这个问题

我的设置如下所示: //callfoopportabley.java

public class CallFooPortably { //name taken from a tutorial, thanks!
    public static void main(String[] args) {
        System.out.println("MIAN START");// debug test
        System.setProperty("jna.library.path",System.getProperty("java.class.path"));
        System.out.println("MAIN Break1");// debug test
        methodOneClass objectA=new methodOneClass();
        objectA.methodOne();
        System.out.println("MAIN inter-method");// debug test
        objectA.methodTwo();
        System.out.println("MAIN END");// debug test
    }
}
我调用库的方法如下: //methodOneClass.java

public class methodOneClass{

      public methodOneClass(){
            System.out.println("Object Created!");
      }

      public void methodOne()  {
            String temp1 = System.getProperty("sun.arch.data.model");
            //provides the JVM bit-ness to the program 

            if (temp1.equals("32")) {
                  System.out.println("Break2");// debug test
                  UserDllLInterface.CLibrary.INSTANCE.Export1();
                  System.out.println("Break3");// debug test
                  UserDllLInterface.CLibrary.INSTANCE.Export2();
                  System.out.println("Break4");// debug test

            } else if (temp1.equals("64")) {
                  System.out.println("Break5");// debug test
                  UserDllLInterface.x64_CLibrary.INSTANCE.Export1();
                  System.out.println("Break6");// debug test
                  UserDllLInterface.x64_CLibrary.INSTANCE.Export2();
                  System.out.println("Break7");// debug test
            }
      }

      public void methodTwo()  {
            String temp2 = System.getProperty("sun.arch.data.model");
            if (temp2.equals("32")) {
                  System.out.println("Break8");// debug test
                  UserDllLInterface.CLibrary.INSTANCE.Export1();
                  System.out.println("Break9");// debug test
                  UserDllLInterface.CLibrary.INSTANCE.Export2();
                  System.out.println("Break10");// debug test
            } else if (temp2.equals("64")) {
                  System.out.println("Break11");// debug test
                  UserDllLInterface.x64_CLibrary.INSTANCE.Export1();
                  System.out.println("Break12");// debug test
                  UserDllLInterface.x64_CLibrary.INSTANCE.Export2();
                  System.out.println("Break13");// debug test
            }
      }
}
最后,图书馆界面如下: //userdllinterface.java

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

public interface UserDllLInterface {
      public static interface CLibrary extends Library { //comes from twall's examples, thanks!
            CLibrary INSTANCE = (CLibrary) Native.loadLibrary("DllExample",CLibrary.class);
            void Export1();
            void Export2();
      }

      public static interface x64_CLibrary extends Library {
            x64_CLibrary INSTANCE = (x64_CLibrary) Native.loadLibrary
              ("x64_DllExample", x64_CLibrary.class);
           void Export1();
           void Export2();
      }
}
< >我的C++源编译成32位和64位DLL: //x64_DllExample.dll//DllExample.dll

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

bool APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved) {
    switch(reason) {
        case DLL_PROCESS_ATTACH:
            printf("You loaded me successfully!\n");
            break;
        case DLL_PROCESS_DETACH:
            printf("You unloaded me successfully!\n");
            break;
        case DLL_THREAD_ATTACH:
            printf("You threaded me successfully!\n");
            break;
        case DLL_THREAD_DETACH:
            printf("You un threaded me successfully!\n");
            break;
    }
    return true;
}

 extern "C" __declspec(dllexport) void Export1() {
     printf("You called the function Export1\n");
 }

extern "C" __declspec(dllexport) void Export2() {
    printf("You called the function Export2\n");
}
但是,我得到的输出是这样的(首先是Java,然后是Windows):


切换到64位JVM会产生类似的结果,首先是Java代码,然后是本机库。我希望有人能帮助解释为什么会发生这种情况。提前感谢您提供的任何帮助

printf
已缓冲。如果添加
fflush(stdout)
在每次
printf
之后,它都会按预期输出。

我回去,按照您的建议重新编译DLL,实际上我收到了预期的结果。谢谢你!我真的希望不必去学习C++如何工作来完成这个项目,但看起来我必须这样做。我可能还会查看Java/JNA端是否有缓冲区刷新选项,因为如果在那里遇到printf,我将无法修改硬件dll。您可以从Java调用
fflush()
,或者调整stdout对象本身使其无缓冲(默认情况下,stderr是无缓冲的;您可以使用该对象进行比较)@technomage谢谢!我会调查这两个!
MIAN START
MAIN Break1
Object Created!
Break5
You loaded me successfully!
You called the function Export1
You un threaded me successfully!
Break6
You called the function Export2
You un threaded me successfully!
Break7
MAIN inter-method
Break11
You called the function Export1
You un threaded me successfully!
Break12
You called the function Export2
You un threaded me successfully!
You unloaded me successfully!
Break13
MAIN END
MIAN START
MAIN Break1
Object Created!
Break5
Break6
Break7
MAIN inter-method
Break11
Break12
Break13
MAIN END
You loaded me successfully!
You called the function Export1
You called the function Export2
You called the function Export1
You called the function Export2
You un threaded me successfully!
You un threaded me successfully!
You un threaded me successfully!
You un threaded me successfully!
You unloaded me successfully!