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中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号