Skip to content

Commit 1c35c49

Browse files
committed
Did the following:
- Added luajit local test folder to gitignore - Reworded and reformatted README.md Updated examples for new changes present in this commit - In all Lua versions, fixed oversight where: - Returned function pointers were not nullable - Sending null function pointers sent Nullable<T> rather than T - It was not possible to send null pointers some places which are handled gracefully by the lua api
1 parent 5fde319 commit 1c35c49

File tree

7 files changed

+299
-128
lines changed

7 files changed

+299
-128
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,4 +458,3 @@ $RECYCLE.BIN/
458458
## Local testing
459459
##
460460
lua-all
461-
luajit

README.md

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@ C# .NET Core 6.0 Lua bindings and helper functions.
66
https://github.com/tilkinsc/Lua.NET
77
Copyright © Cody Tilkins 2022 MIT License
88

9-
```
10-
dotnet add package Lua.NET --version 2.1.0
11-
```
12-
139
Supports Lua5.4 Lua5.3 Lua5.2 Lua5.1 and LuaJIT
1410

15-
Hardcoded to only use doubles and 64-bit integers, so the Lua library will have to be built accordingly. This CAN be changed with manual edits, but it wasn't fun writing this library. This code was made with with the default includes on a 64-bit windows 10 machine using Lua's makefile and LuaJIT. All DLL's are named differently, make sure the name of the Lua dll matches that of the .cs file; will make it easier in the future.
11+
Hardcoded to only use doubles and 64-bit integers, so the Lua library will have to be built accordingly.
12+
This CAN be changed with manual edits, but it wasn't fun writing this library.
13+
This code was made with with the default includes on a 64-bit windows 10 machine using Lua's makefile and LuaJIT.
14+
All DLL's are named differently, make sure the name of the Lua dll matches that of the .cs file; will make it easier in the future and provide the DLLs for you.
1615
```
1716
Lua5.4 - lua544.dll
1817
Lua5.3 - lua536.dll
@@ -21,16 +20,42 @@ Lua5.1 - lua515.dll
2120
LuaJIT - lua51.dll
2221
```
2322

23+
Custom DLLs are supported as long as they don't change any call arguments or return values.
24+
25+
To build Lua, get the Lua source from [Lua.org](https://www.lua.org/download.html) or [LuaJIT](https://luajit.org/download.html).
26+
```bat
27+
make -j24
28+
```
29+
Then rename the dll to the above convention.
30+
31+
# Design Considerations / Usage
32+
33+
Your delegates you pass to functions such as `lua_pushcfunction(...)` should be static.
34+
If you do not use static, then the lifetime of your functions should exceed the lifetime of the Lua the final Lua context you create during the course of the program.
35+
Do not use lambdas.
36+
C# is liable to GC your delegates otherwise.
37+
38+
There are functions prefixed with an underscore.
39+
These functions denote raw DllImported functions.
40+
The reason these exist is because some functions needed a shim function for it to work properly/sanely, i.e. marshaling.
41+
You can write your own functions against those.
42+
For example, if you want a function like lua_pcall but not have to specify an error handler offset you can invoke _lua_pcall(...) in a util class (all functions are static).
43+
This library does not use unsafe, however, going unsafe should work perfectly.
44+
If you are just here to use the library, you can get by without having to worry about the underscore prefixed functions.
45+
46+
# Examples
47+
2448
Example Usage Lua5.4.4:
2549
```C#
26-
namespace LuaNET;
27-
50+
using Lua54;
2851
using static Lua54.Lua;
2952

53+
namespace LuaNET;
54+
3055
class Project
3156
{
3257

33-
public static int lfunc(IntPtr L)
58+
public static int lfunc(lua_State L)
3459
{
3560
lua_getglobal(L, "print");
3661
lua_pushstring(L, "lol");
@@ -41,14 +66,14 @@ class Project
4166
public static void Main(String[] args)
4267
{
4368

44-
IntPtr L = luaL_newstate();
45-
if (L == IntPtr.Zero)
69+
lua_State L = luaL_newstate();
70+
if (L.Handle == UIntPtr.Zero)
4671
{
4772
Console.WriteLine("Unable to create context!");
4873
}
4974
luaL_openlibs(L);
5075
lua_pushcfunction(L, lfunc);
51-
Console.WriteLine(lua_pcallk(L, 0, 0, 0, IntPtr.Zero, null));
76+
Console.WriteLine(lua_pcallk(L, 0, 0, 0, null, null));
5277
lua_close(L);
5378

5479
Console.WriteLine("Success");
@@ -67,7 +92,7 @@ using static LuaJIT.Lua;
6792
class Project
6893
{
6994

70-
public static int lfunc(IntPtr L)
95+
public static int lfunc(lua_State L)
7196
{
7297
lua_getglobal(L, "print");
7398
lua_pushstring(L, "lol");
@@ -78,8 +103,8 @@ class Project
78103
public static void Main(String[] args)
79104
{
80105

81-
IntPtr L = luaL_newstate();
82-
if (L == IntPtr.Zero)
106+
lua_State L = luaL_newstate();
107+
if (L.Handle == UIntPtr.Zero)
83108
{
84109
Console.WriteLine("Unable to create context!");
85110
}

src/Lua51.cs

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
namespace Lua51;
2-
3-
using System;
41
using System.Runtime.InteropServices;
52

63
using voidp = System.UIntPtr;
74
using charp = System.IntPtr;
85
using size_t = System.UInt64;
9-
using lua_State = System.UIntPtr;
106
using lua_Number = System.Double;
117
using lua_Integer = System.Int64;
128

9+
namespace Lua51;
10+
11+
12+
public struct lua_State
13+
{
14+
public UIntPtr Handle;
15+
}
1316

1417
public static class Lua
1518
{
@@ -36,7 +39,7 @@ public struct lua_Debug {
3639
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
3740
public struct luaL_Reg {
3841
string name;
39-
lua_CFunction func;
42+
charp func;
4043
};
4144

4245
[StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
@@ -148,8 +151,13 @@ public static int lua_upvalueindex(int i)
148151
[DllImport(DllName, CallingConvention = Convention)]
149152
public static extern lua_State lua_newthread(lua_State L);
150153

151-
[DllImport(DllName, CallingConvention = Convention)]
152-
public static extern lua_CFunction lua_atpanic(lua_State L, lua_CFunction panicf);
154+
[DllImport(DllName, CallingConvention = Convention, EntryPoint = "lua_atpanic")]
155+
public static extern charp _lua_atpanic(lua_State L, charp panicf);
156+
public static lua_CFunction? lua_atpanic(lua_State L, lua_CFunction? panicf)
157+
{
158+
charp panic = _lua_atpanic(L, panicf == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate<lua_CFunction>(panicf));
159+
return panic == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer<lua_CFunction>(panic);
160+
}
153161

154162
[DllImport(DllName, CallingConvention = Convention)]
155163
public static extern int lua_gettop(lua_State L);
@@ -225,8 +233,13 @@ public static int lua_upvalueindex(int i)
225233
[DllImport(DllName, CallingConvention = Convention)]
226234
public static extern size_t lua_objlen(lua_State L, int idx);
227235

228-
[DllImport(DllName, CallingConvention = Convention)]
229-
public static extern lua_CFunction lua_tocfunction(lua_State L, int idx);
236+
[DllImport(DllName, CallingConvention = Convention, EntryPoint = "lua_tocfunction")]
237+
public static extern charp _lua_tocfunction(lua_State L, int idx);
238+
public static lua_CFunction? lua_tocfunction(lua_State L, int idx)
239+
{
240+
charp ret = _lua_tocfunction(L, idx);
241+
return ret == IntPtr.Zero ? null : Marshal.GetDelegateForFunctionPointer<lua_CFunction>(ret);
242+
}
230243

231244
[DllImport(DllName, CallingConvention = Convention)]
232245
public static extern voidp lua_touserdata(lua_State L, int idx);
@@ -264,8 +277,12 @@ public static int lua_upvalueindex(int i)
264277
// return Marshal.PtrToStringAnsi(_lua_pushfstring(L, fmt, args));
265278
// }
266279

267-
[DllImport(DllName, CallingConvention = Convention)]
268-
public static extern void lua_pushcclosure(lua_State L, lua_CFunction fn, int n);
280+
[DllImport(DllName, CallingConvention = Convention, EntryPoint = "lua_pushcclosure")]
281+
public static extern void _lua_pushcclosure(lua_State L, charp fn, int n);
282+
public static void lua_pushcclosure(lua_State L, lua_CFunction? fn, int n)
283+
{
284+
_lua_pushcclosure(L, fn == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate(fn), n);
285+
}
269286

270287
[DllImport(DllName, CallingConvention = Convention)]
271288
public static extern void lua_pushboolean(lua_State L, int b);
@@ -324,8 +341,12 @@ public static int lua_upvalueindex(int i)
324341
[DllImport(DllName, CallingConvention = Convention)]
325342
public static extern int lua_pcall(lua_State L, int nargs, int nresults, int errfunc);
326343

327-
[DllImport(DllName, CallingConvention = Convention)]
328-
public static extern int lua_cpcall(lua_State L, lua_CFunction func, voidp ud);
344+
[DllImport(DllName, CallingConvention = Convention, EntryPoint = "lua_cpcall")]
345+
public static extern int _lua_cpcall(lua_State L, charp func, voidp ud);
346+
public static int lua_cpcall(lua_State L, lua_CFunction? func, voidp ud)
347+
{
348+
return _lua_cpcall(L, func == null ? IntPtr.Zero : Marshal.GetFunctionPointerForDelegate<lua_CFunction>(func), ud);
349+
}
329350

330351
[DllImport(DllName, CallingConvention = Convention)]
331352
public static extern int lua_load(lua_State L, lua_Reader reader, voidp dt, string chunkname);
@@ -379,13 +400,13 @@ public static void lua_newtable(lua_State L)
379400
lua_createtable(L, 0, 0);
380401
}
381402

382-
public static void lua_register(lua_State L, string n, lua_CFunction f)
403+
public static void lua_register(lua_State L, string n, lua_CFunction? f)
383404
{
384405
lua_pushcfunction(L, f);
385406
lua_setglobal(L, n);
386407
}
387408

388-
public static void lua_pushcfunction(lua_State L, lua_CFunction f)
409+
public static void lua_pushcfunction(lua_State L, lua_CFunction? f)
389410
{
390411
lua_pushcclosure(L, f, 0);
391412
}
@@ -740,16 +761,16 @@ public static void luaL_addsize(luaL_Buffer B, int n)
740761
public static extern charp luaL_prepbuffer(luaL_Buffer B);
741762

742763
[DllImport(DllName, CallingConvention = Convention)]
743-
public static extern void luaL_addlstring(IntPtr B, string s, size_t l);
764+
public static extern void luaL_addlstring(luaL_Buffer B, string s, size_t l);
744765

745766
[DllImport(DllName, CallingConvention = Convention)]
746-
public static extern void luaL_addstring(IntPtr B, string s);
767+
public static extern void luaL_addstring(luaL_Buffer B, string s);
747768

748769
[DllImport(DllName, CallingConvention = Convention)]
749-
public static extern void luaL_addvalue(IntPtr B);
770+
public static extern void luaL_addvalue(luaL_Buffer B);
750771

751772
[DllImport(DllName, CallingConvention = Convention)]
752-
public static extern void luaL_pushresult(IntPtr B);
773+
public static extern void luaL_pushresult(luaL_Buffer B);
753774

754775
public const int LUA_NOREF = -2;
755776
public const int LUA_REFNIL = -1;

0 commit comments

Comments
 (0)