gpt4 book ai didi

winapi - Lua Alien - 调用特定API

转载 作者:行者123 更新时间:2023-12-02 06:22:01 26 4
gpt4 key购买 nike

我目前在使用 Lua 和外星人模块以使用 Win32 API 等 Lua 脚本时遇到了问题。到目前为止,我只遇到了 Alien 的一个问题,即使用使用某些结构(例如 CreateFontIndirect)的 API。

例如:

HFONT CreateFontIndirectA( const LOGFONT& lplf );

日志字体:

typedef struct tagLOGFONT {
LONG lfHeight;
LONG lfWidth;
LONG lfEscapement;
LONG lfOrientation;
LONG lfWeight;
BYTE lfItalic;
BYTE lfUnderline;
BYTE lfStrikeOut;
BYTE lfCharSet;
BYTE lfOutPrecision;
BYTE lfClipPrecision;
BYTE lfQuality;
BYTE lfPitchAndFamily;
TCHAR lfFaceName[LF_FACESIZE];
}LOGFONT, *PLOGFONT;

问题出在字体名称上。我无法让 Lua 将字符串保留在结构本身中,它总是将指针插入结构中。所以我想不出有什么办法可以纯粹从 Lua 使用这个 API。

这就是我所做的工作:

 LOGFONT = alien.defstruct {
{ 'lfHeight', 'long' },
{ 'lfWidth', 'long' },
{ 'lfEscapement', 'long' },
{ 'lfOrientation', 'long' },
{ 'lfWeight', 'long' },
{ 'lfItalic', 'byte' },
{ 'lfUnderline', 'byte' },
{ 'lfStrikeOut', 'byte' },
{ 'lfCharSet', 'byte' },
{ 'lfOutPrecision', 'byte' },
{ 'lfClipPrecision', 'byte' },
{ 'lfQuality', 'byte' },
{ 'lfPitchAndFamily', 'byte' },
{ 'lfFaceName', 'string' } -- This line isn't working properly.
}



gdi32 = alien.load( "gdi32.dll" )
gdi32.CreateFontIndirectA:types {
ret = 'long',
abi = 'stdcall',
'pointer'
}

调用它的示例:

 local lf = LOGFONT:new()
lf.lfHeight = 14
lf.lfWidth = 0
lf.lfEscapement = 0
lf.lfOrientation = 0
lf.lfWeight = 400
lf.lfItalic = 0
lf.lfUnderline = 0
lf.lfStrikeOut = 0
lf.lfCharSet = 0
lf.lfOutPrecision = 0
lf.lfClipPrecision = 0
lf.lfQuality = 0
lf.lfPitchAndFamily = 0
lf.lfFaceName = 'Terminal'

local hFont = gdi32.CreateFontIndirectA( lf() )

调试运行脚本的应用程序显示 api 正在正确调用,除了字体之外,所有内容都已正确传递。我尝试了各种不同的方法来让它工作,但我无法让它按需要运行。

有什么技巧可以解决此问题而不将其他任何内容硬编码到 exe 中吗?

最佳答案

Alien 的字符串类型仅适用于指向字符串的指针,这就是您的示例不起作用的原因。试试这个:

-- LF_FACESIZE = ? -- put the value of the LF_FACESIZE constant here

LOGFONT = alien.defstruct {
{ 'lfHeight', 'long' },
{ 'lfWidth', 'long' },
{ 'lfEscapement', 'long' },
{ 'lfOrientation', 'long' },
{ 'lfWeight', 'long' },
{ 'lfItalic', 'byte' },
{ 'lfUnderline', 'byte' },
{ 'lfStrikeOut', 'byte' },
{ 'lfCharSet', 'byte' },
{ 'lfOutPrecision', 'byte' },
{ 'lfClipPrecision', 'byte' },
{ 'lfQuality', 'byte' },
{ 'lfPitchAndFamily', 'byte' },
{ 'lfFaceName', 'char' }
}

LOGFONT.size = LOGFONT.size + LF_FACESIZE - 1 -- so Alien allocates enough space
-- for the whole array

function get_lfname(lf) -- gets the lfFaceName field as a Lua string
local out = {}
local offset = LOGFONT.offsets.lfFaceName
local buf = lf()
for i = offset, offset+LF_FACESIZE-1 do
local c = buf:get(i, "char")
if c ~= 0 then
out[#out+1] = string.char(c)
else
break
end
end
return table.concat(out)
end

function set_lfname(lf, s) -- sets the Lua string s as the lfFaceName
local offset = LOGFONT.offsets.lfFaceName
local buf = lf()
for i = 1, LF_FACESIZE do
if i <= #s then
buf:set(offset+i, string.byte(string.sub(s, i, i)), "char")
else
buf:set(offset+i, 0, "char")
break
end
end
end

现在只需像往常一样分配 LOFGONF 结构,但使用 get_lfname 和 set_lfname 函数来处理 lfFaceName 属性:

local lf = LOGFONT:new()
lf.lfHeight = 14
lf.lfWidth = 0
lf.lfEscapement = 0
lf.lfOrientation = 0
lf.lfWeight = 400
lf.lfItalic = 0
lf.lfUnderline = 0
lf.lfStrikeOut = 0
lf.lfCharSet = 0
lf.lfOutPrecision = 0
lf.lfClipPrecision = 0
lf.lfQuality = 0
lf.lfPitchAndFamily = 0
set_lfname(lf, 'Terminal')

local hFont = gdi32.CreateFontIndirectA( lf() )

在末尾添加一个数组是 C 编程中结构的常见模式,我忘记了。我将在 Alien 的下一版本中直接支持它。

关于winapi - Lua Alien - 调用特定API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1647943/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com