2016-09-12 11 views
1

現在、2つのスクリーンバッファを使用してC#でコンソールアプリケーションを作成しようとしています(現代GPUのVSyncによく似ています)。 System.Consoleクラスはバッファを切り替える方法を提供しないので、kernel32.dllからいくつかのメソッドをP/Invokeする必要がありました。SetConsoleActiveScreenBufferは画面バッファを表示しません

これがひどく簡素化私の現在のコードです:

static void Main(string[] args) 
{ 
    IntPtr oldBuffer = GetStdHandle(-11); //Gets the handle for the default console buffer 
    IntPtr newBuffer = CreateConsoleScreenBuffer(0, 0x00000001, IntPtr.Zero, 1, 0); //Creates a new console buffer 

    /* Write data to newBuffer */ 

    SetConsoleActiveScreenBuffer(newBuffer); 
} 

次のものが発生しました:

  • 画面がoldBufferに書き込まれたとき、それはnewBuffer
  • を表示する必要があるにもかかわらず、空のままnewBufferの代わりに、データがすぐに表示されます。したがって、私のバッファへの書き込み方法は正しいはずです。
  • SetConsoleActiveScreenBuffer(newBuffer)を呼び出すと、エラーコードは6になります。これは無効なハンドルを意味します。ハンドルが-1ではないので、これは奇妙です。ドキュメントでは無効と扱われています。

私は非常にまれにWin32 APIを使って直接作業しており、一般的なWin32関連の問題をほとんど理解していないことに注意してください。私はどんな助けにも感謝します。

+1

であると考えています。詳細については、この[documentation](http://stackoverflow.com/documentation/winapi/2573/error-reporting-and-handling/8521/error-reported-with-additional-information-on-failure#t=201609121054592086284)を参照してください。情報。読んだら、あなたの質問を更新してください。 – IInspectable

+0

申し訳ありませんが、これで本当に質問全体があまりにも大きく変わることはありません。要点は、バッファを設定することは機能しないと私はなぜ理解していないということです。 –

+1

少なくとも、 "発生した" *リストから余分な観測を削除することができます。観察された挙動が文書化された挙動と一致することを明示的に指摘することにメリットはない。 – IInspectable

答えて

4

コメントにIInspectableが指摘するとおり、dwDesiredAccessをゼロに設定しています。これにより、アクセス権のないハンドルが得られます。そのようなハンドルが便利ないくつかのエッジケースがありますが、これはその1つではありません。

唯一の奇妙な点は、「アクセスが拒否されました」ではなく「無効なハンドル」になっていることです。私はあなたがWindows 7を実行していると推測しているので、ハンドルはカーネルハンドルではなくユーザーモードオブジェクト( "pseudohandle")です。

いずれにしても、dwDesiredAccessGENERIC_READ | GENERIC_WRITEに設定する必要があります(in the sample code)。ハンスは、コメントで指摘したように


はまた、pinvoke.net上の宣言は4バイトの整数ではなく、ポインタサイズの整数として最後の引数を指定して、間違っていました。私は正しい宣言は**明示**そうするように頼まない限り** ** `GetLastError`を呼び出さないでください

[DllImport("kernel32.dll", SetLastError = true)] 
static extern IntPtr CreateConsoleScreenBuffer(
    uint dwDesiredAccess, 
    uint dwShareMode, 
    IntPtr lpSecurityAttributes, 
    uint dwFlags, 
    IntPtr lpScreenBufferData 
    ); 
+2

[DllImport]宣言も正しくない可能性があります。最後の引数はIntPtrです。 –

+0

これは恐らく間違っているpinvoke.netのコードが原因です。 – CodeCaster

+0

@CodeCasterはい、そうです。私はpinvoke.netに何人かの人々が言及していることを知ったので、信頼性があると思った。 –

関連する問題