在 JNA 中使用 printf 和 scanf 的问题

Problems using printf and scanf with JNA

我写了一些 Java JNA 初学者代码。我构建它没有编译错误。

我从 here 下载 JNA 5.6。

我只看到此命令的输出:

System.out.println( "Hello" );

为什么不起作用?

package layout;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
    
interface JNAApiInterface extends Library {
    @SuppressWarnings( "deprecation")
    JNAApiInterface INSTANCE = (JNAApiInterface) Native.loadLibrary(
            Platform.isWindows() ? "msvcrt" : "c", JNAApiInterface.class);
    void printf( String format, Object... args );
    int sprintf( byte[] buffer, String format, Object... args );
    int scanf( String format, Object... args );
}
    
public class JNA01 {
    public static void main( String args[] ) {
        System.out.println( "Hello" );
        JNAApiInterface jnaLib = JNAApiInterface.INSTANCE;
        jnaLib.printf( "Hello World" );
        String testName = null;
        jnaLib.printf( "Please Enter Your Name: \n" );
        jnaLib.scanf( "%s", testName );
        jnaLib.printf( "\nYour name is %s", testName ); 
    }
}

您的 JNA 映射是正确的,但您没有正确使用本机函数。

scanf() 函数要求您为缓冲区分配内存以填充 testName 值,但您向它传递了一个具有空值的不可变 String

该程序打印第一个 Hello,实际上已经打印了 Hello WorldPlease Enter Your Name: ,但是您的 IDE 可能还没有显示此标准输出,因为它正在等待 scanf() 的输入].如果您实际输入了一个值,您会遇到分段错误,因为它会尝试将您输入的名称写入未分配的内存!

要解决这个问题,您需要分配一个缓冲区来填充。将字节数组分配给 testNum,JNA 将自动为其保留分配的内存。然后使用 Native.toString().

解码字节

这个版本的主循环有效:

public static void main(String args[]) {
    System.out.println("Hello");
    JNAApiInterface jnaLib = JNAApiInterface.INSTANCE;
    jnaLib.printf("Hello World\n");
    // this is dangerous as you don't control how long user input is
    // but for learning it's fine, you will crash with longer names
    byte[] testName = new byte[100]; 
    jnaLib.printf("Please Enter Your Name: \n");
    jnaLib.scanf("%s", testName);
    jnaLib.printf("\nYour name is %s", Native.toString(testName));
}