簡體   English   中英

帶有JNA的函數scanf

[英]Function scanf with JNA

我正在嘗試使用JNA的scanf函數:

package importDLLs;

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

public class JNATest {

public interface CLibrary extends Library {
    CLibrary clib = (CLibrary) Native.loadLibrary("msvcrt", CLibrary.class);

    void printf(String format, Object... args);
    int sprintf(byte[] speicher, String format, Object...args);
    int scanf (String format, Object... args1);  
}


public static void main(String[] args) {
    CLibrary.clib.printf("Hello World");
    String test= null;
    args = new String[2];
    args[0]="This is a test";
    args[1]="and another one";
    for ( int i = 0; i < args.length; i++ ){
      CLibrary.clib.printf( "\nArgument %d : %s",i, args[ i ] );
    }

    CLibrary.clib.printf("\nBitte Namen eingeben");
    CLibrary.clib.scanf("%s", test);
    CLibrary.clib.printf("\nyour name is %s",test);
}
}

我是新手,我也讀了很多關於JNA的內容。 但我無法弄清楚如何使用它。 printf函數沒有問題。

這是我得到的錯誤,當我啟動它並在我向控制台寫入內容之后。

Java運行時環境檢測到致命錯誤:

pc = 0x000007fefe531435,pid = 10168,tid = 2964,EXCEPTION_ACCESS_VIOLATION(0xc0000005)

JRE版本:7.0_03-b05 Java VM:Java HotSpot(TM)64位服務器VM(22.1-b02混合模式windows-amd64壓縮oops)有問題的框架:C [msvcrt.dll + 0x61435]

無法編寫核心轉儲。 默認情況下,在客戶端版本的Windows上未啟用小型轉儲

包含更多信息的錯誤報告文件保存為:***** \\ URC Lab \\ hs_err_pid10168.log

如果您想提交錯誤報告,請訪問: http://bugreport.sun.com/bugreport/crash.jsphttp://bugreport.sun.com/bugreport/crash.jsp崩潰發生在Java虛擬機之外的本機代碼中。 查看有問題的框架,了解在哪里報告錯誤。

節目輸出:

 Hello World Argument 0 : This is a test Argument 1 : and another one your name is 

為什么我會收到錯誤,我該如何解決?

仔細閱讀scanf的手冊頁。 每個varargs參數必須是可以寫入掃描項目的內存的地址(即指針)。

Java String是一個不可變對象。 這意味着你不能寫信給它。

可寫緩沖區包括原始數組(例如byte[] ),JNA Memory或NIO緩沖區。 在這種情況下,我建議使用足夠大小的Memory ,然后使用其getString()方法將本機NUL終止的C字符串作為Java String提取。

對於掃描其他類型,JNA提供了ByReference及其子類,它提供了常見的native &var表示法的功能。

一個例子,正如@Gary建議的那樣:

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

public interface JNAApiInterface extends Library {
    JNAApiInterface INSTANCE = (JNAApiInterface) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), JNAApiInterface.class);
    Pointer __iob_func();

    int sizeOfFileStructure = Platform.is64Bit() ? 48 : 32;
    Pointer stdout = JNAApiInterface.INSTANCE.__iob_func().share(sizeOfFileStructure);

    void printf(String format, Object... args);
    int sprintf(byte[] buffer, String format, Object... args);
    int scanf(String format, Object... args);
    int fflush (Pointer stream);
    int puts(String format) ;
    int fprintf(Pointer stream, String format, Object...args) ;
    void setbuf(Pointer stream, String buffer) ;
}

import com.sun.jna.Memory;
import com.sun.jna.platform.win32.Kernel32;

public class JNABucket {
    public static void main(String args[]) {

        JNAApiInterface jnaLib = JNAApiInterface.INSTANCE;
        Kernel32 klib = Kernel32.INSTANCE;
        Memory userName = new Memory(256);

        jnaLib.setbuf(jnaLib.stdout, null);
        jnaLib.printf("Hello World");

        for (int i = 0; i < args.length; i++) {
            jnaLib.printf("\nArgument %d : %s", i, args[i]);
        }

        jnaLib.puts("\nPlease Enter Your Name:\n");

        jnaLib.scanf("%s", userName);
        jnaLib.printf("\nYour name is: %s", userName);

        jnaLib.fprintf(jnaLib.stdout, "\nThis is a Test");

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

    public interface JNAApiInterface extends Library {
        JNAApiInterface INSTANCE = (JNAApiInterface) Native.loadLibrary((Platform.isWindows() ? "msvcrt" : "c"), JNAApiInterface.class);
        Pointer __iob_func();

        int sizeOfFileStructure = Platform.is64Bit() ? 48 : 32;
        Pointer stdout = JNAApiInterface.INSTANCE.__iob_func().share(sizeOfFileStructure);

        void printf(String format, Object... args);
        int sprintf(byte[] buffer, String format, Object... args);
        int scanf(String format, Object... args);
        int fflush (Pointer stream);
        int puts(String format) ;
        int fprintf(Pointer stream, String format, Object...args) ;
        void setbuf(Pointer stream, String buffer) ;
    }


    import com.sun.jna.Memory;
import com.sun.jna.platform.win32.Kernel32;

public class JNABucket {
    public static void main(String args[]) {

        JNAApiInterface jnaLib = JNAApiInterface.INSTANCE;
        Kernel32 klib = Kernel32.INSTANCE;
        Memory testName = new Memory(256);

        jnaLib.setbuf(jnaLib.stdout, null);
        jnaLib.printf("Hello World");
        for (int i = 0; i < args.length; i++) {
            jnaLib.printf("\nArgument %d : %s", i, args[i]);
        }

        jnaLib.puts("\nPlease Enter Your Name:\n");
        jnaLib.scanf("%s", testName);
        jnaLib.printf("\nYour name is: %s", testName);
        jnaLib.fprintf(jnaLib.stdout, "\nthis is a Test");

    }
}

我發現這個解決方案來解決“scanf”無效的內存訪問問題,並立即使用printf和puts函數將文本打印到控制台。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM