.net Linux下Mono中的ReadConsoleOutput、WriteConsoleOutput、ReadConsoleInput功能

.net Linux下Mono中的ReadConsoleOutput、WriteConsoleOutput、ReadConsoleInput功能,.net,winapi,mono,console,pinvoke,.net,Winapi,Mono,Console,Pinvoke,在.Net版本的程序中,我通过p/Invoke使用三个本机WinApi函数: , . 在Linux下如何在Mono中实现此功能 我知道standart系统,控制台类。但是由于某种奇怪的原因,这个类在任何方面都不支持前面提到的winapi函数的功能。如果您重写I/O,以便它跟踪屏幕上应该显示的内容(现在不应该占用太多内存),并且只使用控制台类进行更新,您应该发现Mono的实现可以跟上。Mono还可以通过访问ncurses功能,但坚持使用控制台将更便于携带。您仍然可以通过SetCursorPosit

在.Net版本的程序中,我通过p/Invoke使用三个本机WinApi函数: , . 在Linux下如何在Mono中实现此功能


我知道standart系统,控制台类。但是由于某种奇怪的原因,这个类在任何方面都不支持前面提到的winapi函数的功能。

如果您重写I/O,以便它跟踪屏幕上应该显示的内容(现在不应该占用太多内存),并且只使用
控制台
类进行更新,您应该发现Mono的实现可以跟上。Mono还可以通过访问ncurses功能,但坚持使用
控制台将更便于携带。您仍然可以通过
SetCursorPosition
方法、
BackgroundColor
属性等将其用于定位和着色。

对于ReadConsoleInput使用的等效功能,可以使用库

ReadConsoleOutput在Linux中是不可能的,但您可以将数据存储在自定义屏幕缓冲区中。WriteConsoleOutput可以很容易地使用实现

看看Windows和Posix平台中实现的事件循环。使用的主要函数有:poll()、pipe()、writeInt64()、readInt64()-来自标准libc:

termkeyHandle = LibTermKey.termkey_new( 0, TermKeyFlag.TERMKEY_FLAG_SPACESYMBOL );

// Setup the input mode
Console.Write( "\x1B[?1002h" );
pollfd fd = new pollfd( );
fd.fd = 0;
fd.events = POLL_EVENTS.POLLIN;

pollfd[ ] fds = new pollfd[ 2 ];
fds[ 0 ] = fd;
fds[ 1 ] = new pollfd( );
int pipeResult = Libc.pipe( pipeFds );
if ( pipeResult == -1 ) {
    throw new InvalidOperationException( "Cannot create self-pipe." );
}
fds[ 1 ].fd = pipeFds[ 0 ];
fds[ 1 ].events = POLL_EVENTS.POLLIN;

while ( true ) {
    int pollRes = Libc.poll( fds, 2, -1 );
    if ( pollRes == 0 ) throw new InvalidOperationException( "Assertion failed." );
    if ( pollRes == -1 ) {
        int errorCode = Marshal.GetLastWin32Error();
        if ( errorCode != Libc.EINTR ) {
            throw new InvalidOperationException(string.Format("poll() returned with error code {0}", errorCode));
        }
    }

    bool needProcessInvokeActions = false;
    if ( fds[ 1 ].revents != POLL_EVENTS.NONE ) {
        UInt64 u;
        Libc.readInt64( fds[ 1 ].fd, out u );
        if ( u == 1 ) {
            // Exit from application
            break;
        }
    }

    if ( ( fds[ 0 ].revents & POLL_EVENTS.POLLIN ) == POLL_EVENTS.POLLIN ||
         ( fds[ 0 ].revents & POLL_EVENTS.POLLHUP ) == POLL_EVENTS.POLLHUP ||
         ( fds[ 0 ].revents & POLL_EVENTS.POLLERR ) == POLL_EVENTS.POLLERR ) {
        LibTermKey.termkey_advisereadable( termkeyHandle );
    }

    while ( ( LibTermKey.termkey_getkey( termkeyHandle, ref key ) ) == TermKeyResult.TERMKEY_RES_KEY ) {
        processLinuxInput( key );
    }

    renderer.UpdateRender( );
}

事实上,我还没有看到任何控制台在Mono上有不同的工作方式。