JNR-FFI を使用して文字テーブルを CMD 画面バッファに出力するとクラッシュする

PHPz
リリース: 2024-02-22 12:50:16
転載
810 人が閲覧しました

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 中国語 Web サイトの他の関連記事を参照してください。

ソース:stackoverflow.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!