首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将复杂结构传递给Windows API

将复杂结构传递给Windows API
EN

Stack Overflow用户
提问于 2019-08-22 05:20:28
回答 1查看 201关注 0票数 6

我正在尝试通过Perl6和(当然) NativeCall从Windows API中使用GetConsoleScreenBufferInfo(HANDLE, PCONSOLE_SCREEN_BUFFER_INFO)函数。

我想我已经正确地设置了函数所需的CONSOLE_SCREEN_BUFFER_INFO结构,但是当我尝试转储其内容时,代码在调用后崩溃。

这是演示问题的最短(不完全但很接近)的方法:

代码语言:javascript
运行
复制
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

任何关于崩溃发生的原因以及如何修复它的提示都是非常受欢迎的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-23 04:10:35

对于作为结构的CONSOLE_SCREEN_BUFFER_INFO的成员,您需要使用HAS而不是has,因为这些成员是嵌入的,而不是由指针引用的(这是Perl6的默认设置)。

完成此操作后,还可以删除TWEAK,这样代码就会显示为

代码语言:javascript
运行
复制
class CONSOLE_SCREEN_BUFFER_INFO is repr("CStruct") {
  HAS COORD $.dwSize;
  HAS COORD $.dwCursorPosition;
  has WORD $.wAttributes;
  HAS SMALL_RECT $.srWindow;
  HAS COORD $.dwMaximumWindowSize;
}
票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57599297

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档