2012-06-08 2 views
1

У меня есть DLL, написанная на C#, которая используется сценариями Lua. Сценарии «требуют CLRPackage». До сих пор я мог load_assembly() и import_type(), чтобы получить классы и методы в моей DLL. Я передаю простые значения и строки, и все работает.Передача коллекции C# обратно в Lua

Нет Мне нужно передать родовую коллекцию обратно в Lua. Я считаю, что Lua увидит таблицу, но мне не ясно, как создать эту таблицу на C# и передать ее обратно.

This похоже на аналогичный вопрос, но я не вижу, как его реализовать. Есть ли другое решение или одно с фрагментированным фрагментом кода?

ответ

4

Теперь мне нужно передать родовую коллекцию обратно в Lua. Я считаю, что то, что увидит Луа, - это таблица

Это не будет. Lua увидит объект CLR (скорее, прокси userdata для объекта CLR).

Если у вас есть метод в C классе # как это:

public List<string> GetList() 
{ 
    return new List<string> { "This", "bar", "is", "a" }; 
} 

В стороне Lua (после того, как вы загрузили модуль, схватил класс и экземпляр его, как, скажем, foo):

local list = foo:GetList() 
print(list) 

Это даст вам что-то вроде System.Collections.Generic.List1[System.String]: 33476626. Это пользовательские данные, а не стол, так что вы не можете использовать next или pairs перебрать его, вы должны взаимодействовать с ним, как это было C# List<string>:

local it = list:GetEnumerator() 
while it:MoveNext() do 
    print(it.Current) 
end 

Это очень некрасиво, не- идиоматический Lua (даже не идиоматический C#, учитывая, что вы используете foreach в C#), но я не думаю, что существует автоматическая сортировка между типами LuaInterface и CLR. Своего трудно сказать; Документация LuaInterface практически отсутствует.

Вы можете написать свои собственные процедуры маршал между Lua и CLR типами, как:

function listToTable(clrlist) 
    local t = {} 
    local it = clrlist:GetEnumerator() 
    while it:MoveNext() do 
     t[#t+1] = it.Current 
    end 
    return t 
end 
   
... 
   
local list = listToTable(foo:GetList()) 
for key, val in pairs(list) do 
    print(key,val) 
end 

Добавить dictToTable и вы будете в значительной степени охвачены.

+0

Большое спасибо. Я довольно новичок в C# и Lua, и это очень полезно. Я сейчас дома, но буду экспериментировать с этим, когда вернусь к работе. Я думал, что альтернативой может быть предоставление моего собственного итератора. Мой C# будет вызывать GetNumberOfItems() и GetNextItem(), или, возможно, GetItem (int index), а затем мой Lua может зацикливаться, чтобы получить элементы по своему желанию. Это решение кажется немного менее уродливым, чем то, что я рассматривал. Как вы думаете? – halm

+0

Эй, грязь, любая идея, как получить размер списка в lua? – pragnesh

+0

Userdata является прокси для объекта C#, поэтому он должен иметь свой интерфейс. Другими словами, [list: Count] (https://msdn.microsoft.com/en-us/library/5s3kzhec%28v=vs.110%29.aspx) должен сделать трюк. – Mud

Смежные вопросы