FinnTheHuman
FinnTheHuman

Reputation: 1155

How do I compile a C++ dll to work with Lua? (I'm getting Error loading module)

When I type require ("C:/Path/To/Dll/mylib.dll") during an interactive Lua session I get this error

error loading module 'C:\...\mylib.dll' from file 'C:\Program Files\Lua\5.3.4\clib\libgcc_s_dw2-1.dll'
%1 is not a valid Win32 application

When I do:

f = package.loadlib("C:/Path/To/Dll/mylib.dll")
f()

Lua crashes, and if I run the debugger, I can see it crashes here:

l_noret luaG_errormsg (lua_State *L) {
    if (L->errfunc != 0) {
        StkId errfunc = restorestack(L, L->errfunc);
        if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);//<<< HERE
        setobjs2s(L, L->top, L->top - 1);
        setobjs2s(L, L->top - 1, errfunc);
        L->top++;
        luaD_call(L, L->top - 2, 1, 0);
    }
    luaD_throw(L, LUA_ERRRUN);
}

The error originates from here:

LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
    const lua_Number *v = lua_version(L);
    if (v != lua_version(NULL))
        luaL_error(L, "multiple Lua VMs detected");//<<< HERE
    else if (*v != ver)
        luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", ver, *v);
    /* check conversions number -> integer types */
    lua_pushnumber(L, -(lua_Number)0x1234);
    if (lua_tointeger(L, -1) != -0x1234 ||
        lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
        luaL_error(L, "bad conversion number->int;"
              " must recompile Lua with proper settings");
    lua_pop(L, 1);

}

I might have done something wrong while installing the binaries. These values are in my PATH:

C:\Program Files\Lua\5.3.4\
C:\Program Files\Lua\5.3.4\clibs

I also have these environment variables:

LUA_CPATH: C:\Program Files\Lua\5.3.4\clib\libgcc_s_dw2-1.dll
LUA_DEV: C:\Program Files\Lua\5.3.4\src
LUA_PATH: C:\Program Files\Lua\5.3.4\?.luac

To compile my code, I included Lua's source code in my solution (I don't think this is how it's done, so this is probably another issue).

Here's my header file:

#pragma once
#ifdef __cplusplus
extern "C" {
#endif
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"

    int l_cond ( lua_State * L );
    int l_bor ( lua_State * L );
    int l_band ( lua_State * L );
    int l_bxor ( lua_State * L );
    int l_bnot ( lua_State * L );
    int l_lshift ( lua_State * L );
    int l_rshift ( lua_State * L );
#ifdef __cplusplus
}
#endif

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <SDKDDKVer.h>
#include <windows.h>

Here's my C++ code:

#include "mylib.h"

#ifdef __cplusplus
extern "C" {
#endif

static const luaL_Reg lib[] = {
    { "cond", l_cond },
    { "bor", l_bor },
    { "band", l_band },
    { "bxor", l_bxor },
    { "bnot", l_bnot },
    { "lshift", l_lshift },
    { "rshift", l_rshift },
    {NULL, NULL}
};


__declspec( dllexport ) int luaopen_mylib ( lua_State *L )
{
    luaL_newlib ( L, lib );
}

static int l_cond ( lua_State *L )
{
    /*if ( lua_gettop ( L ) < 3 )
    {
        return luaL_error ( L, "l_cond expecting 3 arguments" );
    }*/

    lua_toboolean ( L, 1 ) ? lua_pushvalue ( L, 2 ) : lua_pushvalue ( L, 3 );
    return 1;
}

static int l_bor ( lua_State *L )
{
    /*if ( lua_gettop ( L ) < 2 )
    {
        return luaL_error ( L, "l_bor expecting 2 arguments" );
    }*/

    lua_Integer a = lua_tointeger ( L, 1 );
    lua_Integer b = lua_tointeger ( L, 2 );

    lua_pushinteger ( L, a | b );
    return 1;
}

static int l_band ( lua_State *L )
{
    /*if ( lua_gettop ( L ) < 2 )
    {
        return luaL_error ( L, "l_band expecting 2 arguments" );
    }*/

    lua_Integer a = lua_tointeger ( L, 1 );
    lua_Integer b = lua_tointeger ( L, 2 );

    lua_pushinteger ( L, a & b );
    return 1;
}

static int l_bxor ( lua_State *L )
{
    /*if ( lua_gettop ( L ) < 2 )
    {
        return luaL_error ( L, "l_bxor expecting 2 arguments" );
    }*/

    lua_Integer a = lua_tointeger ( L, 1 );
    lua_Integer b = lua_tointeger ( L, 2 );

    lua_pushinteger ( L, a ^ b );
    return 1;
}

static int l_bnot ( lua_State *L )
{
    /*if ( lua_gettop ( L ) < 1 )
    {
        return luaL_error ( L, "l_bxor expecting 1 argument" );
    }*/

    lua_Integer a = lua_tointeger ( L, 1 );

    lua_pushinteger ( L, ~a );
    return 1;
}

static int l_lshift ( lua_State *L )
{
    /*if ( lua_gettop ( L ) < 2 )
    {
        return luaL_error ( L, "l_lshift expecting 2 arguments" );
    }*/

    lua_Integer value = lua_tointeger ( L, 1 );
    lua_Integer shift = lua_tointeger ( L, 2 );

    lua_pushinteger ( L, value << shift );
    return 1;
}

static int l_rshift ( lua_State *L )
{
    /*if ( lua_gettop ( L ) < 2 )
    {
        return luaL_error ( L, "l_rshift expecting 2 arguments" );
    }*/

    lua_Integer value = lua_tointeger ( L, 1 );
    lua_Integer shift = lua_tointeger ( L, 2 );

    lua_pushinteger ( L, value >> shift );
    return 1;
}
#ifdef __cplusplus
}
#endif

besides those two files, as mentioned above, I also included the entirety of Lua's source code in my project. It all compiles, but I get that error when trying to load. This is all very new to me, I'm aware there's probably more than just one thing wrong with my attempt.

Upvotes: 1

Views: 785

Answers (1)

Alexander Altshuler
Alexander Altshuler

Reputation: 3064

You shouldn't include Lua source code into your project. You should link with Lua DLL.

Update:

The simplest way to link with Lua DLL, just include this line (fix path and library name of course):

#pragma comment(lib, "C:\\path\\to\\Lua5.X.lib")

Upvotes: 1

Related Questions