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++; } } }
如上所述,在 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:
尝试用谷歌搜索,但没有找到任何我能理解的东西。有什么帮助吗?
有人指出 WriteConsoleOutputCharacterW()
中的最后一个参数应该是指向 long var 而不是 int 的指针。
改变这个:
int lpNumberOfCharsWritten = 0;“WroteCMD()”中的
对此:
Pointer lpNumberOfCharsWritten = Runtime.getSystemRuntime().getMemoryManager().allocate( Runtime.getSystemRuntime().findType( TypeAlias.int32_t ).size() );
解决了这个问题。我使用 int 作为内存地址,在本例中尝试写入地址 0。
以上是使用 JNR-FFI 将字符表输出到 CMD 屏幕缓冲区崩溃的详细内容。更多信息请关注PHP中文网其他相关文章!