映射C#类通过DLL Lua函数函数、DLL、Lua

2023-09-05 04:17:41 作者:北念

在我的LuaTest命名空间我有一类称为行星。在C#code倒像是这样的:

In my "LuaTest" namespace I have a class called "Planet". The C# code reads like this:

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的脚本,我写了:

Then I built LuaTest.dll and copied this file to the same folder where my Lua script is saved. In the Lua script I wrote:

--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()

然而,这片code不起作用。 Lua的跨preTER引发此错误:

However, this piece of code does not work. Lua interpreter throws this error:

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

我怀疑我的LuaTest组件一点都没有装。谁能指出哪里做错了?我非常AP preciate它,因为我一直坚持这个问题好几天了。

I suspect that my LuaTest assembly is not loaded at all. Could anyone point out where I did wrong? I would very much appreciate it, since I've been stuck by this problem for days.

此外,它可能是有益的补充,我LuaInterface.dll是重建版本.NET4.0环境。

Also it might be helpful to add that my LuaInterface.dll is the rebuilt version in .NET4.0 environment.

推荐答案

我花了一些时间在结合C#DLL到Lua。您的文章是有帮助的,但缺了点什么。 下面的解决方案应该工作

I spent some time in binding C# dll to lua. Your posts were helpful but something was missing. The following solution should work:

(一定要改变你的编译器的.NET Framework 3.5或更低!)

(Make sure to change your compiler to .NET Framework 3.5 or lower!)

Planet.dll:

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

namespace Planets
{
    public class Planet
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { this.name = value; }
        }

        private float diameter;
        public float Diameter
        {
            get { return diameter; }
            set { this.diameter = value; }
        }
        private int cntContinents;
        public int CntContinents
        {
            get { return cntContinents; }
            set { this.cntContinents = value; }
        }

        public Planet()
        {
            Console.WriteLine("Constructor 1");
            this.name = "nameless";
            this.diameter = 0;
            this.cntContinents = 0;
        }

        public Planet(string n, float d, int k)
        {
            Console.WriteLine("Constructor 2");
            this.name = n;
            this.diameter = d;
            this.cntContinents = k;
        }

        public void testMethod()
        {
            Console.WriteLine("This is a Test!");
        }
    }
}

使用的code以上,将其粘贴到您的类库项目,并与.NET小于或等于3.5编译。

Use the code above, paste it into your class library project and compile it with .NET smaller or equal 3.5.

所产生的DLL的位置需要由LUA环境是已知的。在clibs-folder或其他知名的卢阿系统路径粘贴如。然后尝试使用下面的LU​​A的例子。它应该工作。

The location of the generated DLL needs to be known by the lua enviroment. Paste it e.g at "clibs"-folder or another well known lua system path. Then try to use the following lua example. It should work.

Test1.lua:(方案1与CLRPackage进口)

Test1.lua: (Option 1 with "import" from CLRPackage)

require "luanet"
require "CLRPackage"
import "Planet"
local PlanetClass = luanet.import_type("Planets.Planet")
print(PlanetClass)
local PlanetObject1 = PlanetClass()
print(PlanetObject1)
local PlanetObject2 = PlanetClass("Earth",6371.00*2,7)
print(PlanetObject1.Name)
PlanetObject1.Name = 'Mars'
print(PlanetObject1.Name)
print(  "Planet " .. 
        PlanetObject2.Name .. 
        " is my home planet. Its diameter is round about " .. 
        PlanetObject2.Diameter .. "km." .. 
        " Our neighour is " .. 
        PlanetObject1.Name)

Test2.lua:(选项2load_assembly)

Test2.lua: (Option 2 with "load_assembly")

require "luanet"
require "CLRPackage"
luanet.load_assembly("Planet")
local PlanetClass = luanet.import_type("Planets.Planet")
print(PlanetClass)
local PlanetObject1 = PlanetClass()
print(PlanetObject1)
local PlanetObject2 = PlanetClass("Earth",6371.00*2,7)
print(PlanetObject1.Name)
PlanetObject1.Name = 'Mars'
print(PlanetObject1.Name)
print(  "Planet " .. 
        PlanetObject2.Name .. 
        " is my home planet. Its diameter is round about " .. 
        PlanetObject2.Diameter .. "km." .. 
        " Our neighour is " .. 
        PlanetObject1.Name)

在这两种情况下,控制台输出将是这样的:

In both cases the console output will look like this:

的proxyType(Planets.Planet):18643596 的 构造1 的 Planets.Planet:33574638 的 构造2 的 无名的 火星的 的地球是我家的星球。它的直径是圆的约12742公里。我们的邻居火星的

ProxyType(Planets.Planet): 18643596 Constructor 1 Planets.Planet: 33574638 Constructor 2 nameless Mars Planet Earth is my home planet. Its diameter is round about 12742km. Our neighbour is Mars

我希望它可以帮助你们中的一些。

I hope its helps some of you.

修改1: 顺便说一句,从Lua调用方法如下:

Edit 1: by the way, a method call from lua looks like this:

PlanetObject1:testMethod()
PlanetObject2:testMethod()

编辑2: 我发现不同的dll的whitch需要进行不同的处理。一个需要进口 - 函数和其他所需的load_assembly - 函数。记住这也许在心中!

Edit 2: I found different dll's whitch needed to be handled differently. One needed the "import"-function and another needed the "load_assembly"-function. Keep that maybe in mind!