通过dll将C#类映射到Lua函数

在我的"LuaTest"命名空间中,我有一个名为"Planet"的类。C# 代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LuaInterface;

namespace LuaTest
{
    public class Planet
    {
        public Planet(string name)
        {
            this.Name = name;
        }
        public Planet() : this("NoName") { }
        public string Name
        {
            get;
            private set;
        }

        public void printName()
        {
            Console.WriteLine("This planet's name is {0}", Name);
        }
    }
}

然后我构建了LuaTest.dll并将此文件复制到保存Lua脚本的相同文件夹中。在Lua脚本中我写道:

--define Path for required dlls
package.cpath = package.cpath .. ";" .. "/?.dll"
package.path = package.path .. ";" .. "/?.dll/"
require 'luanet'
luanet.load_assembly("LuaTest")
local Planet = luanet.import_type("LuaTest.Planet")
local planet = Planet("Earth")
planet.printName()

然而,这段代码不起作用。Lua解释器会抛出这个错误:

lua: dllTest.lua:7: attempt to call local 'Planet' (a nil value)

我怀疑我的LuaTest程序集根本没有加载。请问有人能指出我哪里错了吗?我非常感激,因为我被这个问题困扰了很多天。

另外,可能有所帮助,我的LuaInterface.dll是在.NET4.0环境中重建的版本。

点赞
用户920858
用户920858

所以我花了很多时间。让我真正感到困扰的是尝试让枚举工作。最终,我放弃了我的项目,转向一个非常简化的控制台应用程序,它与之非常相似(具有讽刺意味的是也命名为“LuaTest”)。

编辑:我注意到初始的“luanet.load_assembly(”LuaTest“)”似乎是多余的。它可以与之一起工作,或者惊讶的是没有它也可以工作。

另一个编辑:正如我下面编辑不好的评论所述,当我删除了:

print(luanet.LuaTest.Pointless)

它就停止工作了(LuaTest.Pointless变成了nil)。但是添加luanet.load_assembly(“LuaTest”)然后使它工作。可能某种奇怪的隐式加载在打印或仅在表达类型时存在。非常奇怪(tm)。

无论如何,它对我而言似乎是有效的(注意:经过大量实验)。我不知道为什么您的失败,我没有注意到任何真正的区别,但在这里是我的所有代码,以防其他人可以发现关键的区别:

使用System;
使用System.Collections.Generic;
使用System.Linq;
使用System.Text;

使用LuaInterface;

namespace LuaTest
  {
  public class Program
      {
      static void Main(string[] args)
          {
          Lua lua = new Lua();
          lua.DoFile("test.lua");
          }

      public int some_member = 3;
      }

  public class Pointless
      {
      public enum AnEnum
        {
        One,
        Two,
        Three
        };

      public static string aStaticInt = "This is static.";
      public double i;
      public string n = "Nice";
      public AnEnum oneEnumVal = AnEnum.One;
      private AnEnum twoEnumVal = AnEnum.Two;
      private string very;

      public Pointless(string HowPointLess)
        {
        i = 3.13;
        very = HowPointLess;
        }

      public class MoreInnerClass
        {
        public string message = "More, please!";
        }

      public void Compare(AnEnum inputEnum)
        {
        if (inputEnum == AnEnum.Three)
          Console.WriteLine("Match.");
        else
          Console.WriteLine("Fail match.");
        }
      }

  }

和test.lua:

luanet.load_assembly("LuaTest")

--Pointless是LuaTest程序集中的一个类
local Pointless = luanet.import_type("LuaTest.Pointless")

print(Pointless)
--给出 'ProxyType(LuaTest.Pointless):46104728

print(Pointless.aStaticInt)
--'This is static.'
--如果不是静态的,就会失败,正如我们所期望的那样

--实例化一个'Pointless'
local p = Pointless("Very")

print(p)
--给出'LauTest.Pointless:12289376'

--现在我们可以进入Pointless内部的项目
--类(无论如何,这个实例)。

local e = p.AnEnum;
print(e)
--ProxyType(LuaTest.Pointless+AnEnum):23452342
--我想+必须指定它是一种类型?

print(p.i)
--3.14

print(p.oneEnumVal)
--给出“ One:0 ”

print(p.twoEnumVal)
--给出'twoEnumVal' ...私人
--表现非常不同。

print(e.Two:ToString())
--给出“ Two ”

local more = p.MoreInnerClass()
print(more.message)
--'More, Please!'

--在此脚本中创建枚举值,
--将其返回以与枚举进行比较。
local anotherEnumVal = p.AnEnum.Three

p:Compare(anotherEnumVal)
- 输出“ Match”
2013-02-01 02:51:00
用户2146396
用户2146396

在过去的几天里,我一直在为 LuaInterface 这个项目工作,需要使用这个精确的功能。我偶然发现了一个 Lua 代码片段,正好是完美的解决方案(参见参考文献1)。在寻找这个解决方案时,我注意到了这个问题,并想给出我的见解。

要运用这个解决方案,我仅需要在初始化 LuaInterface Lua 对象时运行 CLRPackage 代码。不过,使用 require 语句同样有效。

参考文献1中提供的代码允许使用 import 语句,类似于 C# 的 using 语句。一旦导入了一个程序集,它的成员就可以在全局命名空间中访问。import 语句消除了使用 load_assembly 或 import_type 的必要性(除非你需要使用来自不同程序集的同名成员。在这种情况下,类似于 C# 的 using NewTypeName = Assembly.OldTypeName,需要使用 import_type)。

import "LuaTest"
planet = Planet("Earth")
planet:printName()

这个包还非常适合枚举类型!

关于使用此包的更多信息,请参见参考文献2。

希望这有所帮助!

参考文献1:https://github.com/stevedonovan/MonoLuaInterface/blob/master/bin/lua/CLRPackage.lua

参考文献2:http://penlight.luaforge.net/project-pages/penlight/packages/LuaInterface/

2013-03-26 19:09:09