I am trying to use the GetConsoleScreenBufferInfo(HANDLE, PCONSOLE_SCREEN_BUFFER_INFO)
function from the Windows API using Perl 6 and (of course) NativeCall.
I think I have set up the CONSOLE_SCREEN_BUFFER_INFO
struct the function needs correctly, but the code crashes after the call when I try to dump its content.
This is the shortest (not quite but close) way to demonstrate the problem:
use NativeCall;
constant \HANDLE := Pointer[void];
constant \SHORT := int16;
constant \USHORT := uint16;
constant \WORD := uint16;
constant \DWORD := uint32;
constant \BOOL := int32;
constant \STD_OUTPUT_HANDLE := -11;
constant \STD_INPUT_HANDLE := -10;
class COORD is repr('CStruct') {
has SHORT $.X;
has SHORT $.Y;
}
class SMALL_RECT is repr("CStruct") {
has SHORT $.Left;
has SHORT $.Top;
has SHORT $.Right;
has SHORT $.Bottom;
};
class CONSOLE_SCREEN_BUFFER_INFO is repr("CStruct") {
has COORD $.dwSize;
has COORD $.dwCursorPosition;
has WORD $.wAttributes;
has SMALL_RECT $.srWindow;
has COORD $.dwMaximumWindowSize;
submethod TWEAK {
$!dwSize := COORD.new;
$!dwCursorPosition := COORD.new;
$!srWindow := SMALL_RECT.new;
$!dwMaximumWindowSize := COORD.new;
}
}
# C: BOOL WINAPI GetConsoleScreenBufferInfo(_In_ HANDLE hConsoleOutput, _Out_ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
sub GetConsoleScreenBufferInfo(HANDLE, CONSOLE_SCREEN_BUFFER_INFO is rw) is native("Kernel32.dll") returns BOOL { * };
sub GetStdHandle(DWORD) is native('Kernel32') returns Pointer[void] { * };
my CONSOLE_SCREEN_BUFFER_INFO
$info = CONSOLE_SCREEN_BUFFER_INFO.new;
my HANDLE
$handle-o = GetStdHandle( STD_OUTPUT_HANDLE );
dd $info;
say "GetConsoleScreenBufferInfo ", GetConsoleScreenBufferInfo( $handle-o, $info );
say "Will I live?";
dd $info; #crashes without notice
Any hints as to why the crash occurs and how to fix it are very welcome.
You need to use HAS
instead of has
for the members of CONSOLE_SCREEN_BUFFER_INFO
that are structures as these are embedded instead of referenced by pointer (which is the Perl6 default).
Once you do that, you can drop the TWEAK
as well so the code will read
class CONSOLE_SCREEN_BUFFER_INFO is repr("CStruct") {
HAS COORD $.dwSize;
HAS COORD $.dwCursorPosition;
has WORD $.wAttributes;
HAS SMALL_RECT $.srWindow;
HAS COORD $.dwMaximumWindowSize;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With