Rumah > Java > Ranap apabila mengeluarkan jadual aksara ke penimbal skrin CMD menggunakan JNR-FFI

Ranap apabila mengeluarkan jadual aksara ke penimbal skrin CMD menggunakan JNR-FFI

PHPz
Lepaskan: 2024-02-22 12:50:16
ke hadapan
1038 orang telah melayarinya

php小编西瓜为您带来关于使用JNR-FFI在Java中将字符表输出到CMD屏幕缓冲区导致崩溃的问题。JNR-FFI是一个用于Java和本地代码交互的工具,但在处理字符表输出时可能会导致CMD屏幕缓冲区崩溃的情况。本文将为您解析这一问题的原因并提供解决方案,让您轻松解决这一技术难题。

问题内容

我正在尝试用 java 编写一个库,它将使用 c++ 代码来直接访问 cmd 中控制台屏幕缓冲区的写入。我已经成功打印了一次,但之后崩溃了,退出代码为 0xc0000005

我使用了 jnr-ffi 库。此代码现在打印出动画的第一帧,在 if 上暂停一秒钟并崩溃。

这是代码:

import jnr.ffi.libraryloader;
import jnr.ffi.pointer;

public class main {

    public interface kernel32 {
        kernel32 instance = libraryloader.create(kernel32.class).load("kernel32");

        int generic_read = 0x80000000;
        int generic_write = 0x40000000;
        int file_share_read = 0x00000001;
        int file_share_write = 0x00000002;
        int console_textmode_buffer = 1;

        pointer createconsolescreenbuffer(int dwdesiredaccess, int dwsharemode, pointer lpsecurityattributes, int dwflags, pointer lpscreenbufferdata);
        void setconsoleactivescreenbuffer(pointer hconsoleoutput);
        int writeconsoleoutputcharacterw(pointer hconsoleoutput, char[] lpcharacter, int nlength, int dwwritecoord, int lpnumberofcharswritten);
    }

    private static final int nscreenwidth = 240;
    private static final int nscreenheight = 135;

    static kernel32 kernel32 = kernel32.instance;

    private static pointer hconsole = kernel32.createconsolescreenbuffer(
            kernel32.generic_write | kernel32.generic_read,
            kernel32.file_share_read | kernel32.file_share_write,
            null,
            kernel32.console_textmode_buffer,
            null
    );

    public static void writecmd(char[] screen){
        try {
            if (screen.length == (nscreenwidth * nscreenheight) + 1) {
                int lpnumberofcharswritten = 0;
                system.out.println(kernel32.writeconsoleoutputcharacterw(hconsole, screen, (nscreenwidth * nscreenheight) + 1, 0, lpnumberofcharswritten));
            }
        } catch (exception t) {
            t.printstacktrace();
        }
    }

    public static void main(string[] args) {
        kernel32.setconsoleactivescreenbuffer(hconsole);

        char[] screen = new char[(nscreenwidth * nscreenheight) + 1];
        for (int i = 0; i < screen.length - 1; i++) {
            screen[i] = '-';
        }
        screen[screen.length - 1] = '\0';

        int position = 0;
        while(true){
            screen[position] = '#';
            writecmd(screen);
            screen[position] = '-';
            position++;
        }
    }
}
Salin selepas log masuk

如上所述,在 cmd 中运行它会打印第一帧,冻结一秒钟并且毫无例外地崩溃,但在 intellij 控制台中运行它给了我退出代码“0xc0000005”,并在事件查看器中发现了这一点:

Faulting application name: java.exe, version: 20.0.2.0, time stamp: 0x75f7bb13
Faulting module name: KERNELBASE.dll, version: 10.0.22621.2715, time stamp: 0x10f6a783
Exception code: 0xc0000005
Fault offset: 0x00000000000b5bdc
Faulting process id: 0x0x5B98
Faulting application start time: 0x0x1DA1CB1377C8871
Faulting application path: C:\Program Files\Java\jdk-20\bin\java.exe
Faulting module path: C:\Windows\System32\KERNELBASE.dll
Report Id: 97a532d2-82fd-4b33-a399-ee74ea9e606d
Faulting package full name: 
Faulting package-relative application ID:
Salin selepas log masuk

尝试用谷歌搜索,但没有找到任何我能理解的东西。有什么帮助吗?

解决方法

有人指出 WriteConsoleOutputCharacterW() 中的最后一个参数应该是指向 long var 而不是 int 的指针。

改变这个: int lpNumberOfCharsWritten = 0;“WroteCMD()”中的

对此: Pointer lpNumberOfCharsWritten = Runtime.getSystemRuntime().getMemoryManager().allocate( Runtime.getSystemRuntime().findType( TypeAlias.int32_t ).size() );

解决了这个问题。我使用 int 作为内存地址,在本例中尝试写入地址 0。

Atas ialah kandungan terperinci Ranap apabila mengeluarkan jadual aksara ke penimbal skrin CMD menggunakan JNR-FFI. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan