2012-12-26 39 views
0

我有這個功能,我想返回多個值,但我不知道如何實現你給這個Lua的外星人返回多個值

function GetDiskSpace(_disk) 
    require("alien") 
    local kernel32 = alien.load("kernel32.dll") 
    kernel32.GetDiskFreeSpaceExA:types("int", "pointer", "int", "int", "int") 

    if kernel32.GetDiskFreeSpaceExA(_disk, _avail_space, _disk_space, _free_space) ~= 0 then 
      return _avail_space, _disk_space, _free_space 
      --[[or like this return kernel32.GetDiskFreeSpaceExA(_disk, _avail_space, _disk_space, _free_space) 
      GetDiskFreeSpaceExA should retun non zero if function ran properly, 
      and should retun additional values if those are given 
      (btw values are __int64 i'm not sure if I specified them correct, maybe 
      I should set them as "long" instead of "int") 
      either way it return only function value and nil's. 
      --]] 
    else 
      print("GetDiskSpace returned error.") 
    end 
end 

hdd_a, hdd_b, hdd_c = GetDiskSpace("C:\\") 

回答

0

的型號規格是錯誤的幾個原因。第一個參數是類型"string"而不是"pointer"。你必須寫"ref int"而不僅僅是"int"作爲參考(或指針)到int。你還必須指定ABI爲"stdcall"

當使用"ref int"自變量調用該函數時,會傳遞一個虛擬0值,但會得到一個附加的返回值,因此GetDiskFreeSpaceExA有效返回4個結果。

對於結果的值類型uint64_t值得擔心。據我所知,外星人支持64位整數,所以下面的代碼只返回低32位的磁盤空間:

function GetDiskSpace(_disk) 
    require("alien") 
    local kernel32 = alien.load("kernel32.dll") 
    kernel32.GetDiskFreeSpaceExA:types { ret="int", abi="stdcall", 
     "string", "ref int", "ref int", "ref int" } 
    local ok, _avail_space, _disk_space, _free_space = 
     kernel32.GetDiskFreeSpaceExA(_disk, 0, 0, 0) 
    assert(ok == 1, "GetDiskSpace returned error.") 
    return _avail_space, _disk_space, _free_space 
end 

hdd_a, hdd_b, hdd_c = GetDiskSpace("C:\\") 

爲了解決這個問題,你可以添加64位整數支持通過修改Alien的源代碼並重建它。