简体   繁体   中英

AccessViolationException when calling C# from Lua

I'm trying to use Lua (C) with C#, I've imported some functions to test this, and everything seems to work, until I try to call a C# function from Lua.

static void Main(string[] args)
{
    var L = Lua.luaL_newstate();
    Lua.luaL_openlibs(L);
    Lua.lua_register(L, "test", Test);
    Lua.luaL_dostring(L, "test()");
}

static int Test(IntPtr L)
{
    Console.WriteLine("Test from lua->C#");
    return 0;
}

If I run this code, I get the test message, but just after that it throws an AccessViolationException here:

// #define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
public static int luaL_dostring(IntPtr L, string s)
{
    if (luaL_loadstring(L, s) != 0)
        return 1;

    if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0) // <<<<<<<<<<<<<<<<<<<<<<<<
        return 1;

    return 0;
}

Here is my entire import code:

public static class Lua
{
    public const int LUA_MULTRET = -1;

    //[return: MarshalAs(UnmanagedType.SysInt)]
    public delegate int LuaNativeFunction(IntPtr L);

    [DllImport("lua51.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern IntPtr luaL_newstate();

    [DllImport("lua51.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern void luaL_openlibs(IntPtr L);

    [DllImport("lua51.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int luaL_loadbuffer(IntPtr L, [MarshalAs(UnmanagedType.LPStr)] string buff, int size, [MarshalAs(UnmanagedType.LPStr)] string name);

    // LUA_API int lua_resume (lua_State *L, int nargs)
    [DllImport("lua51.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int lua_resume(IntPtr L, int nargs);

    // static int lua_pcall(lua_State*L,int nargs,int nresults,int errfunc)
    [DllImport("lua51.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int lua_pcall(IntPtr L, int nargs, int nresults, int errfunc);

    // static void lua_pushcclosure(lua_State*L,lua_CFunction fn,int n)
    [DllImport("lua51.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int lua_pushcclosure(IntPtr L, LuaNativeFunction fn, int n);

    // static void lua_setfield(lua_State*L,int idx,const char*k);
    [DllImport("lua51.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
    public static extern int lua_setfield(IntPtr L, int idx, [MarshalAs(UnmanagedType.LPStr)] string k);

    // LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s)
    public static int luaL_loadstring(IntPtr L, string s)
    {
        return luaL_loadbuffer(L, s, s.Length, s);
    }

    // #define luaL_dostring(L, s) (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))
    public static int luaL_dostring(IntPtr L, string s)
    {
        if (luaL_loadstring(L, s) != 0)
            return 1;

        if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0)
            return 1;

        return 0;
    }

    // #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
    public static void lua_register(IntPtr L, string n, LuaNativeFunction f)
    {
        lua_pushcfunction(L, f);
        lua_setglobal(L, n);
    }

    // #define lua_pushcfunction(L,f)   lua_pushcclosure(L, (f), 0)
    public static void lua_pushcfunction(IntPtr L, LuaNativeFunction f)
    {
        lua_pushcclosure(L, f, 0);
    }

    // #define lua_setglobal(L,s)lua_setfield(L,(-10002),(s))
    public static void lua_setglobal(IntPtr L, string s)
    {
        lua_setfield(L, -10002, s);
    }
}

Since I read that this can be caused by a type mismatch in the return value of the delegate: I'm running Windows 7 x64, the Lua dll is x86, and the project is set to use x86 as well. I've also tried to set a return marshal for LuaNativeFunction, since this was suggested somewhere else, but that didn't change anything.

[return: MarshalAs(UnmanagedType.I4)]
public delegate int LuaNativeFunction(IntPtr L);

Does somebody have an idea what the problem might be?

Update: Using a x64 Lua lib with x64 target solved it, so I guess that is the problem somehow, but I don't quite understand why .

The Lua DLL is compiled with CDecl calling convention and you need to specify this on all DllImport attributes, and all delegates used as callback. So for example your LuaNativeFunction delegate need to be declared as :

[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl‌​)]
[return: MarshalAs(UnmanagedType.I4)]
public delegate int LuaNativeFunction(IntPtr L);

Regards,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM