首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lua Alien -调用特定接口

Lua Alien -调用特定接口
EN

Stack Overflow用户
提问于 2009-10-30 11:56:31
回答 2查看 1.8K关注 0票数 3

我目前遇到了一个问题,当我玩弄Lua和外星人模块来使用Lua脚本中的Win32 API等。到目前为止,我只有一个关于alien的问题,那就是使用使用特定结构的API,比如CreateFontIndirect。

例如:

代码语言:javascript
复制
HFONT CreateFontIndirectA( const LOGFONT& lplf );

LOGFONT:

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

这是我在一定程度上得到的结果:

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

下面是一个调用它的示例:

代码语言:javascript
复制
 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被正确调用,除font face之外的所有内容都被正确传递。我尝试了各种不同的方法来让它工作,但我不能让它按需要进行。

在不将任何其他东西硬编码到exe中的情况下,有什么技巧可以修复这个问题吗?

EN

回答 2

Stack Overflow用户

发布于 2009-10-30 21:56:34

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

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

代码语言:javascript
复制
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中对其提供直接支持。

票数 3
EN

Stack Overflow用户

发布于 2009-11-01 07:45:34

非常感谢mascarenhas的回复,这个解决方案起作用了。我确实必须调整你的set_lfname函数,因为偏移量+i -1没有对齐,并且覆盖了结构中的lfPitchAndFamily字节,去掉了-1,它工作得很好。:)

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1647943

复制
相关文章

相似问题

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