Вызов CreateFile с использованием JNA приводит к UnsatisfiedLinkError: Ошибка при поиске функции «CreateFile»: указанная процедура не может быть найдена - PullRequest
4 голосов
/ 13 сентября 2011

Я пытаюсь вызвать функцию Win32 CreateFile в Windows 7, используя JNA, с целью сделать реализацию Java этого ответа , чтобы проверить, используется ли файл другим процессом.

Код, который у меня есть на данный момент:

import com.sun.jna.Native;
import com.sun.jna.examples.win32.Kernel32;

public class CreateFileExample {

    static int GENERIC_ACCESS = 268435456;
    static int EXCLUSIVE_ACCESS = 0;
    static int OPEN_EXISTING = 3;

    public static void main(String[] args) {
        Kernel32 kernel32 = 
            (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
        kernel32.CreateFile("c:\\file.txt", GENERIC_ACCESS, EXCLUSIVE_ACCESS,
            null, OPEN_EXISTING, 0, null);
    }
}

Однако, выполнение этого вызывает исключение:

java.lang.UnsatisfiedLinkError: Error looking up function 'CreateFile': The specified procedure could not be found.

Если я изменю "kernel32" в вызове loadLibrary на что-то недопустимое, тогда вместо этого я получу The specified module could not be found, так что это говорит о том, что DLL правильно найдена по пути к библиотеке, но что-то не так с тем, как я звонить CreateFile.

Есть идеи, что я делаю не так?


CreateFile определяется в com.sun.jna.examples.win32.Kernel32 как:

public abstract com.sun.jna.examples.win32.W32API.HANDLE CreateFile(
    java.lang.String arg0,
    int arg1,
    int arg2,
    com.sun.jna.examples.win32.Kernel32.SECURITY_ATTRIBUTES arg3,
    int arg4,
    int arg5,
    com.sun.jna.examples.win32.W32API.HANDLE arg6);

Ответы [ 2 ]

6 голосов
/ 13 сентября 2011

Windows API имеет функции ASCII и Unicode (CreateFileA и CreateFileW), поэтому вам нужно указать, какую из них вы хотите при вызове loadLibrary():

Kernel32 kernel32 = 
    (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, W32APIOptions.UNICODE_OPTIONS); 

Кроме того, на самом деле вам не нужно звонить loadLibrary() вручную:

Kernel32 kernel32 = Kernel32.INSTANCE;
0 голосов
/ 14 февраля 2013

попробуйте написать такую ​​функцию


HANDLE hDeviceUSB = Kernel32.INSTANCE.CreateFile(szCom,
                    GENERIC_READ | GENERIC_WRITE, 
                    0,              
                    null,          
                    OPEN_EXISTING,  
                    0,              
                    null);
...