Skip to content

Lack of official documentation for creating shared modules #147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
yiv1 opened this issue Apr 11, 2025 · 18 comments · May be fixed by #150
Open

Lack of official documentation for creating shared modules #147

yiv1 opened this issue Apr 11, 2025 · 18 comments · May be fixed by #150

Comments

@yiv1
Copy link

yiv1 commented Apr 11, 2025

lua.zig

const std = @import("std");
const zlua = @import("zlua");
const Lua = zlua.Lua;

fn add(L: *Lua) i32 {
    const arg = L.toInteger(1) catch 0;

    std.debug.print("Argument from Lua: {}\n", .{arg});

    L.pushInteger(arg + 1);

    return 1;
}

fn module(lua: *Lua) i32 {
    const functions = [_]zlua.FnReg{
        zlua.FnReg{ .name = "add", .func = zlua.wrap(add) },
    };

    Lua.newLib(lua, &functions);
    // lua.registerFns("lualib", &functions);

    return 1;
}

comptime {
    _ = zlua.exportFn("lualib", module);
}

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});

    const moduleLua = b.createModule(.{
        .root_source_file = b.path("./src/lua.zig"),
        .target = target,
        .optimize = .ReleaseFast,
    });

    const libraryLua = b.addLibrary(.{
        .linkage = .dynamic,
        .name = "lualib",
        .root_module = moduleLua,
        .use_llvm = true,
    });

    libraryLua.addIncludePath(b.path("./src/lua-5.4.1/src"));
    libraryLua.addLibraryPath(b.path("./src/lua-5.4.1"));
    libraryLua.linkSystemLibrary("lua54"); // lua54.dll ?

    const zlua = b.dependency("zlua", .{
        .target = target,
        .optimize = .ReleaseFast,
        .lang = .lua54,
        .shared = true,
    });
    libraryLua.root_module.addImport("zlua", zlua.module("zlua"));

    b.installArtifact(libraryLua);
}

build.zig.zon

.{
    .name = ***,
    .version = "0.0.0",
    .fingerprint = ****,
    .minimum_zig_version = "0.14.0",
    .dependencies = .{
        .zlua = .{
            .url = "git+https://github.com/natecraddock/ziglua#891945ef9c2bffcd06050c4836d414428ed7d95a",
            .hash = "zlua-0.1.0-hGRpC2rgBACFhBjc9s9dGN37ZaTu7rNVZZqduwitv4O7",
        },
    },
    .paths = .{
        "build.zig",
        "build.zig.zon",
        "src",
    },
}

zig build - is running successfully, but

test.lua

local lualib = require("lualib")

local result = lualib.add(42)
print("Result:", result)

Executing the script

..\src\lua-5.4.1\lua54.exe test.lua
C:\***\lua-5.4.1\lua54.exe: error loading module 'lualib' from file '.\lualib.dll':
        The specified procedure could not be found.

stack traceback:
        [C]: in ?
        [C]: in function 'require'
        test.lua:1: in main chunk
        [C]: in ?

Additional information:

PS C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64> .\dumpbin.exe /imports "c:\***\lualib.dll"
Microsoft (R) COFF/PE Dumper Version 14.37.32825.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file c:\***\lualib.dll

File Type: DLL

  Section contains the following imports:

    lua54.dll
             1800277C0 Import Address Table
             1800276A8 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 luaL_checkstack
                           0 luaL_checkversion_
                           0 lua_createtable
                           0 lua_pushcclosure
                           0 lua_pushinteger
                           0 lua_setfield
                           0 lua_settop
                           0 lua_tointegerx

    lua.dll
             180027808 Import Address Table
             1800276F0 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 _GetPEImageBase
                           0 __main
                           0 __mingw_GetSectionCount
                           0 __mingw_GetSectionForAddress
                           0 __mingw_TLScallback

    api-ms-win-crt-runtime-l1-1-0.dll
             180027838 Import Address Table
             180027720 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 _execute_onexit_table
                           0 _exit
                           0 _initialize_onexit_table
                           0 _initterm
                           0 _initterm_e
                           0 _register_onexit_function
                           0 abort

    KERNEL32.dll
             180027878 Import Address Table
             180027760 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 AcquireSRWLockExclusive
                           0 GetLastError
                           0 ReleaseSRWLockExclusive
                           0 Sleep
                           0 VirtualProtect
                           0 VirtualQuery
                           0 WriteFile

    api-ms-win-crt-stdio-l1-1-0.dll
             1800278B8 Import Address Table
             1800277A0 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 __acrt_iob_func
                           0 __stdio_common_vfprintf
                           0 fwrite

  Summary

        1000 .buildid
        2000 .data
        2000 .pdata
        6000 .rdata
        1000 .reloc
       23000 .text
        1000 .tls
PS C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64> .\dumpbin.exe /exports "c:\***\lualib.dll"
Microsoft (R) COFF/PE Dumper Version 14.37.32825.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file c:\***\lualib.dll

File Type: DLL

  Section contains the following exports for lualib.dll

    00000000 characteristics
           0 time date stamp
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 00001000 _DllMainCRTStartup
          2    1 00001010 luaopen_lualib

  Summary

        1000 .buildid
        2000 .data
        2000 .pdata
        6000 .rdata
        1000 .reloc
       23000 .text
        1000 .tls

Test folder structure:

  • lua.dll
  • lua54.dll
  • lualib.dll
  • test.lua

If i remove lua.dll, i got

..\src\lua-5.4.1\lua54.exe test.lua
C:\***\lua-5.4.1\lua54.exe: error loading module 'lualib' from file '.\lualib.dll':
        The specified module could not be found.

stack traceback:
        [C]: in ?
        [C]: in function 'require'
        test.lua:1: in main chunk
        [C]: in ?

I'm confusing. What should I do to get the dll to work?

@robbielyman
Copy link
Collaborator

hmmm. firstly in your build script it's not necessary to link your lualib library against the system Lua—importing ziglua will link against the copy that ziglua built.

secondly i'm unable to reproduce this on my macOS machine: i get the following output

robbie scratch % lua test.lua
Argument from Lua: 42
Result: 43

one thing to be aware of is that since Windows has multiple C ABIs, you should check that both the lua.exe you're using and the library you're compiling have the same ABI target, whether that's MSVC or MinGW?

@yiv1
Copy link
Author

yiv1 commented Apr 12, 2025

@robbielyman Thanks for the quick response!

I'm glad it worked for you, so the code is correct. I just need to find the problem on my side.

I'm not very familiar with MSVC and MinGW and can't answer this question.

What I think is happening:

ziglua links lua.dll
ideally i should link lua54.dll, because where you will use require there is already lua54.dll
I don't need lua.dll binding in my dll (or change filename?)

I need to write a shared module for version 5.4.1
zlua have 5.4.7, which could be a potential problem?

I have lua-5.4.1 sources. And already compiled.

hmmm. firstly in your build script it's not necessary to link your lualib library against the system Lua—importing ziglua will link against the copy that ziglua built.
Can I skip lua compilation from ziglua side?

compile.bat

::
:: Compiles Lua
::

::
:: Set up environment
::

:: Start local variable scope
@SETLOCAL

:: Locate 'vcvarsall.bat'
@IF NOT "%VS120COMNTOOLS%"=="" @SET VSVARSALL=%VS120COMNTOOLS%..\..\VC\vcvarsall.bat
@IF NOT "%VS140COMNTOOLS%"=="" @SET VSVARSALL=%VS140COMNTOOLS%..\..\VC\vcvarsall.bat
@IF "%VSVARSALL%"=="" @GOTO ENDSETUP

:: Identify the target architecture
@IF NOT "%PROCESSOR_ARCHITECTURE%"=="" (
    @IF "%PROCESSOR_ARCHITECTURE%"=="x86" @SET ARCH=x86
    @IF "%PROCESSOR_ARCHITECTURE%"=="x64" @SET ARCH=x64
    @IF "%PROCESSOR_ARCHITECTURE%"=="AMD64" @SET ARCH=amd64
)
@IF "%ARCH%"=="" @GOTO ENDSCRIPT

:: Call the setup script
@CALL "%VSVARSALL%" %ARCH%
@ECHO ON

:ENDSETUP

::
:: Process files
::

:: Move down into 'src'
@PUSHD src

:: Clean up files from previous builds
@IF EXIST *.o @DEL *.o
@IF EXIST *.obj @DEL *.obj
@IF EXIST *.dll @DEL *.dll
@IF EXIST *.exe @DEL *.exe

:: Compile all .c files into .obj
@CL /MD /O2 /c /DLUA_BUILD_AS_DLL *.c

:: Rename two special files
@REN lua.obj lua54.o
@REN luac.obj lua54c.o

:: Link up all the other .objs into a .lib and .dll file
@LINK /DLL /IMPLIB:lua54.lib /OUT:lua54.dll *.obj

:: Link lua into an .exe
@LINK /OUT:lua54.exe lua54.o lua54.lib

:: Create a static .lib
@LIB /OUT:lua54-static.lib *.obj

:: Link luac into an .exe
@LINK /OUT:lua54c.exe lua54c.o lua54-static.lib

:: Move back up out of 'src'
@POPD

:: Copy the library and executable files out from 'src'
@COPY /Y src\lua54.exe lua54.exe
@COPY /Y src\lua54c.exe lua54c.exe
@COPY /Y src\lua54.dll lua54.dll

:ENDSCRIPT

:: End local variable scope
@ENDLOCAL

I have worked cpp code that is built using cl.exe

cl /O2 /LD /MT /std:c++17 lualib.cpp /link

lualib.cpp

// #pragma lets you provide additional information to the compiler
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "lua-5.4.1/src/lua54.lib")

#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <winuser.h>
#include <rpcndr.h>
#include <sysinfoapi.h>
#include <cstdint>
#include <string>
#include <thread>
#include <iostream>
#include <fstream>

#define LUA_LIB
#define LUA_BUILD_AS_DLL

#include "lua-5.4.1/src/lua.hpp"

...

static struct luaL_Reg InitStruct[] = {
    { "Now", Now },

    { nullptr, nullptr }
};

extern "C" LUALIB_API int luaopen_lualib(lua_State *L) {
    luaL_newlib(L, InitStruct);

    return 1;
}

I want to port module from cpp to zig.

one thing to be aware of is that since Windows has multiple C ABIs, you should check that both the lua.exe you're using and the library you're compiling have the same ABI target, whether that's MSVC or MinGW?
Will the information provided help to answer this question?

An interpreter that already contains lua54.dll shows a similar error when running test.lua

error loading module 'lualib' from file '.\lualib.dll':
	The specified procedure could not be found.

@yiv1
Copy link
Author

yiv1 commented Apr 12, 2025

I tried using another lua54.exe from lua-5.4.2_Win64_bin.zip https://luabinaries.sourceforge.net/download.html and get the same error

.\lua54.exe test.lua
C:\***\lua54.exe: error loading module 'lualib' from file 'C:\***\lualib.dll':
        The specified procedure could not be found.

stack traceback:
        [C]: in ?
        [C]: in function 'require'
        test.lua:1: in main chunk
        [C]: in ?

@yiv1
Copy link
Author

yiv1 commented Apr 12, 2025

If I don't have lua installed globally, where do the sources come from?

https://github.com/natecraddock/ziglua/blob/main/build/lua.zig

const lua_base_source_files = [_][]const u8{
    "src/lapi.c",
    "src/lcode.c",
    "src/ldebug.c",
    "src/ldump.c",
    "src/lfunc.c",
    "src/lgc.c",
    "src/llex.c",
    "src/lmem.c",
    "src/lobject.c",
    "src/lopcodes.c",
    "src/lparser.c",
    "src/lstate.c",
    "src/lstring.c",
    "src/ltable.c",
    "src/ltm.c",
    "src/lundump.c",
    "src/lvm.c",
    "src/lzio.c",
    "src/lauxlib.c",
    "src/lbaselib.c",
    "src/ldblib.c",
    "src/liolib.c",
    "src/lmathlib.c",
    "src/loslib.c",
    "src/ltablib.c",
    "src/lstrlib.c",
    "src/loadlib.c",
    "src/linit.c",
};

const lua_52_source_files = lua_base_source_files ++ [_][]const u8{
    "src/ldo.c",
    "src/lctype.c",
    "src/lbitlib.c",
    "src/lcorolib.c",
};

const lua_53_source_files = lua_base_source_files ++ [_][]const u8{
    "src/ldo.c",
    "src/lctype.c",
    "src/lbitlib.c",
    "src/lcorolib.c",
    "src/lutf8lib.c",
};

const lua_54_source_files = lua_base_source_files ++ [_][]const u8{
    "src/ldo.c",
    "src/lctype.c",
    "src/lcorolib.c",
    "src/lutf8lib.c",
};

@robbielyman
Copy link
Collaborator

the build.zig.zon has dependencies for each version of Lua that are fetched and compiled into ziglua.

@yiv1
Copy link
Author

yiv1 commented Apr 14, 2025

I got additional information:

simple lualib.c

#include <windows.h>
#include <stdio.h>
#include <wchar.h>
#include <winuser.h>
#include <rpcndr.h>
#include <sysinfoapi.h>

#define LUA_LIB
#define LUA_BUILD_AS_DLL

#include "lua-5.4.1/src/lua.h"
#include "lua-5.4.1/src/lauxlib.h"
#include "lua-5.4.1/src/luaconf.h"

static int add(lua_State *L) {
    int d1 = luaL_checkinteger(L, 1);

    lua_pushinteger(L, d1 + 1);

    return 1;
}

static const luaL_Reg InitStruct[] = {
    { "add", add },

    { NULL, NULL }
};

// LUALIB_API = __declspec(dllexport)
LUALIB_API int luaopen_lualib(lua_State *L) {
    luaL_newlib(L, InitStruct);

    return 1;
}

build.zig

const std = @import("std");

pub fn build(b: *std.Build) !void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const lualib = b.addSharedLibrary(.{
        .name = "lualib",
        .target = target,
        .optimize = optimize,
    });

    const flags = [_][]const u8{
        "-std=gnu99",
    };

    lualib.addIncludePath(b.path("./lua-5.4.1/src"));

    lualib.addCSourceFile(.{
        .file = b.path("lualib.c"),
        .flags = &flags,
    });

    lualib.addObjectFile(b.path("./lua-5.4.1/lua54.lib"));

    lualib.linkLibC();

    b.installArtifact(lualib);
}

Test folder structure:

  • lua54.dll
  • lualib.dll
  • test.lua

test.lua

local lualib = require("lualib")

local result = lualib.add(42)
print("Result:", result)

Result:

..\src\lua-5.4.1\lua54.exe test.lua
Result: 43
PS C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64> .\dumpbin.exe /exports "C:\***\zig-out\bin\lualib.dll"
Microsoft (R) COFF/PE Dumper Version 14.37.32825.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\***\zig-out\bin\lualib.dll

File Type: DLL

  Section contains the following exports for lualib.dll

    00000000 characteristics
           0 time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 luaopen_lualib = luaopen_lualib

  Summary

        1000 .buildid
        2000 .data
        2000 .pdata
       3C000 .rdata
        1000 .reloc
       4B000 .text
        1000 .tls

I see the difference in dumpbin

dont work

    ordinal hint RVA      name

          1    0 00001000 _DllMainCRTStartup
          2    1 00001010 luaopen_lualib

works successfully

    ordinal hint RVA      name

          1    0 00001000 luaopen_lualib = luaopen_lualib

Does order matter? Can _DllMainCRTStartup break luaopen_ lookup?

@robbielyman
Copy link
Collaborator

we're quickly reaching the edge of my knowledge, but for comparison, here's nm -g lualib.so for my (working) reproduction of your (nonworking) code:

robbie scratch % nm -g lualib.so
0000000000008068 D ___dso_handle
                 U ___error
0000000000008068 D __mh_dylib_header
0000000000008088 D __mh_execute_header
                 U _luaL_checkstack
                 U _luaL_checkversion_
                 U _lua_createtable
                 U _lua_pushcclosure
                 U _lua_pushinteger
                 U _lua_setfield
                 U _lua_settop
                 U _lua_tointegerx
0000000000000680 T _luaopen_lualib
                 U _os_unfair_lock_lock
                 U _os_unfair_lock_unlock
                 U _pthread_threadid_np
                 U _write
                 U dyld_stub_binder

@yiv1
Copy link
Author

yiv1 commented Apr 14, 2025

@robbielyman Thank you for still being with me :)

robbie scratch % nm -g lualib.so

Unfortunately this information does not help me at all.


I managed to remove _DllMainCRTStartup with little hack

const std = @import("std");
const zlua = @import("zlua");
const Lua = zlua.Lua;

fn add(L: *Lua) i32 {
    const arg = L.toInteger(1) catch 0;
    std.debug.print("Argument from Lua: {}\n", .{arg});
    L.pushInteger(arg + 1);
    return 1;
}

fn module(lua: *Lua) i32 {
    const functions = [_]zlua.FnReg{
        zlua.FnReg{ .name = "add", .func = zlua.wrap(add) },
    };

    Lua.newLib(lua, &functions);

    return 1;
}

comptime {
    _ = zlua.exportFn("lualib", module);
}

pub fn _DllMainCRTStartup() callconv(.winapi) std.os.windows.BOOL {
    return std.os.windows.TRUE;
}

But it didn't help.

Worked DLL from C

Microsoft (R) COFF/PE Dumper Version 14.37.32825.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file C:\***\zig-out\bin\lualib.dll

File Type: DLL

  Section contains the following exports for lualib.dll

    00000000 characteristics
           0 time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 luaopen_lualib = luaopen_lualib

  Summary

        1000 .buildid
        2000 .data
        2000 .pdata
       3C000 .rdata
        1000 .reloc
       4B000 .text
        1000 .tls

nonworking DLL from zig

Microsoft (R) COFF/PE Dumper Version 14.37.32825.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file c:\***\lualib.dll

File Type: DLL

  Section contains the following exports for lualib.dll

    00000000 characteristics
           0 time date stamp
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 luaopen_lualib

  Summary

        1000 .buildid
        2000 .data
        2000 .pdata
        6000 .rdata
        1000 .reloc
       23000 .text
        1000 .tls

I don't see any critical difference. This is a dead end...

@natecraddock
Copy link
Owner

I've never tested shared modules on Windows. I'll try to see if I can debug this sometime soon

@yiv1
Copy link
Author

yiv1 commented Apr 14, 2025

I hope the information below helps.

Worked DLL from C

PS C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64> .\dumpbin.exe /imports "c:\***\worked\lualib.dll"
Microsoft (R) COFF/PE Dumper Version 14.37.32825.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file c:\***\worked\lualib.dll

File Type: DLL

  Section contains the following imports:

    lua54.dll
             180084F30 Import Address Table
             180084D10 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           9 luaL_checkinteger
                          10 luaL_checkversion_
                          26 luaL_setfuncs
                          37 lua_createtable
                          5A lua_pushinteger

    api-ms-win-crt-runtime-l1-1-0.dll
             180084F60 Import Address Table
             180084D40 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 _execute_onexit_table
                           0 _exit
                           0 _initialize_onexit_table
                           0 _initterm
                           0 _initterm_e
                           0 _register_onexit_function
                           0 abort

    KERNEL32.dll
             180084FA0 Import Address Table
             180084D80 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 AcquireSRWLockExclusive
                           0 CreateToolhelp32Snapshot
                           0 DeleteCriticalSection
                           0 EnterCriticalSection
                           0 ExitProcess
                           0 GetConsoleMode
                           0 GetConsoleScreenBufferInfo
                           0 GetFileSizeEx
                           0 GetLastError
                           0 InitializeCriticalSection
                           0 K32GetModuleFileNameExW
                           0 LeaveCriticalSection
                           0 Module32First
                           0 Module32Next
                           0 ReadFile
                           0 ReleaseSRWLockExclusive
                           0 RtlCaptureContext
                           0 RtlLookupFunctionEntry
                           0 RtlVirtualUnwind
                           0 SetConsoleMode
                           0 SetConsoleTextAttribute
                           0 SetFilePointerEx
                           0 Sleep
                           0 TlsGetValue
                           0 VirtualAlloc
                           0 VirtualFree
                           0 VirtualProtect
                           0 VirtualQuery
                           0 WriteFile

    api-ms-win-crt-stdio-l1-1-0.dll
             180085090 Import Address Table
             180084E70 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 __acrt_iob_func
                           0 __stdio_common_vfprintf
                           0 fwrite

    ntdll.dll
             1800850B0 Import Address Table
             180084E90 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 NtClose
                           0 NtCreateFile
                           0 NtCreateSection
                           0 NtDeviceIoControlFile
                           0 NtLockFile
                           0 NtMapViewOfSection
                           0 NtQueryInformationFile
                           0 NtQueryObject
                           0 NtQueryVolumeInformationFile
                           0 NtUnmapViewOfSection
                           0 RtlEqualUnicodeString
                           0 RtlGetFullPathName_U
                           0 RtlWaitOnAddress

    api-ms-win-crt-heap-l1-1-0.dll
             180085120 Import Address Table
             180084F00 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 calloc
                           0 free

    api-ms-win-crt-string-l1-1-0.dll
             180085138 Import Address Table
             180084F18 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 strlen
                           0 strncmp

  Summary

        1000 .buildid
        2000 .data
        2000 .pdata
       3C000 .rdata
        1000 .reloc
       4B000 .text
        1000 .tls

nonworking DLL from zig

PS C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.37.32822\bin\Hostx64\x64> .\dumpbin.exe /imports "c:\***\lualib.dll"
Microsoft (R) COFF/PE Dumper Version 14.37.32825.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file c:\***\lualib.dll

File Type: DLL

  Section contains the following imports:

    lua54.dll
             1800277A0 Import Address Table
             180027688 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           D luaL_checkstack
                          10 luaL_checkversion_
                          37 lua_createtable
                          58 lua_pushcclosure
                          5A lua_pushinteger
                          70 lua_setfield
                          78 lua_settop
                          80 lua_tointegerx

    lua.dll
             1800277E8 Import Address Table
             1800276D0 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 _GetPEImageBase
                           0 __main
                           0 __mingw_GetSectionCount
                           0 __mingw_GetSectionForAddress
                           0 __mingw_TLScallback

    api-ms-win-crt-runtime-l1-1-0.dll
             180027818 Import Address Table
             180027700 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 _execute_onexit_table
                           0 _exit
                           0 _initialize_onexit_table
                           0 _initterm
                           0 _initterm_e
                           0 _register_onexit_function
                           0 abort

    KERNEL32.dll
             180027858 Import Address Table
             180027740 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 AcquireSRWLockExclusive
                           0 GetLastError
                           0 ReleaseSRWLockExclusive
                           0 Sleep
                           0 VirtualProtect
                           0 VirtualQuery
                           0 WriteFile

    api-ms-win-crt-stdio-l1-1-0.dll
             180027898 Import Address Table
             180027780 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 __acrt_iob_func
                           0 __stdio_common_vfprintf
                           0 fwrite

  Summary

        1000 .buildid
        2000 .data
        2000 .pdata
        6000 .rdata
        1000 .reloc
       23000 .text
        1000 .tls

@yiv1
Copy link
Author

yiv1 commented Apr 16, 2025

I managed to put together a working example.

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});

    const zig_mod = b.addSharedLibrary(.{
        .name = "lualib",
        .root_source_file = b.path("./src/lualib.zig"),
        .target = target,
        .optimize = .ReleaseFast,
    });

    zig_mod.linkLibC();

    zig_mod.addIncludePath(b.path("./src/lua-5.4.1/src"));
    zig_mod.addObjectFile(b.path("./src/lua-5.4.1/src/lua54.lib"));

    b.installArtifact(zig_mod);
}

lualib.zig

const std = @import("std");

pub const c = @cImport({
    @cInclude("luaconf.h");
    @cInclude("lua.h");
    @cInclude("lualib.h");
    @cInclude("lauxlib.h");
});

fn add(L: ?*c.lua_State) callconv(.C) c_int {
    const arg = c.luaL_checkinteger(L, 1);

    std.debug.print("Argument from Lua: {}\n", .{arg});

    c.lua_pushinteger(L, arg + 1);

    return 1;
}

const lib_fn_reg = [_]c.luaL_Reg{ .{ .name = "add", .func = &add }, c.luaL_Reg{} };

export fn luaopen_lualib(L: ?*c.lua_State) callconv(.C) c_int {
    c.luaL_checkversion(L);
    c.lua_createtable(L, 0, 1);
    c.luaL_setfuncs(L, &lib_fn_reg, 0);

    return 1;
}

Test folder structure:

  • lua54.dll
  • lualib.dll
  • test.lua
./lua54.exe test.lua
Argument from Lua: 42
Result: 43

As you see _DllMainCRTStartup it doesn't matter at all.
Null-terminated row c.luaL_Reg{} is important for the DLL to work correctly.

I couldn't use c.luaL_newlib(L, &lib_fn_reg); because translate-c breaks the luaL_newlibtable macro.

@natecraddock
Copy link
Owner

Null-terminated row c.luaL_Reg{} is important for the DLL to work correctly.

Interesting. Glad you got it working. It would be nice if you could use ziglua directly though.

I got my Windows environment running and I'm debugging this right now. I'll let you know if I can figure it out

@yiv1
Copy link
Author

yiv1 commented Apr 17, 2025

One of the criteria for using ziglua will be the ability to rename the name of the associated library from lua.dll to lua54.dll. Currently the hardcode "lua" is used, this limits my capabilities.

I also don't know if 5.4.7 will fit my 5.4.1 environment, it's a potential risk for me.

@robbielyman
Copy link
Collaborator

i’m sure we’d consider a PR adding more flexibility to that part of the process. it is a bit odd from my perspective to be posting so frequently in the issue tracker of a project you’re not using.

@natecraddock
Copy link
Owner

it is a bit odd from my perspective to be posting so frequently in the issue tracker of a project you’re not using.

I think this is a use case ziglua should support so I'm okay with this.


One of the criteria for using ziglua will be the ability to rename the name of the associated library from lua.dll to lua54.dll. Currently the hardcode "lua" is used, this limits my capabilities.

@yiv1 let me make sure I'm understanding correctly.

You have your own copy of Lua 5.4.1 that you have compiled. You want to use Ziglua with this version of lua and build a shared module?

@yiv1
Copy link
Author

yiv1 commented Apr 17, 2025

@robbielyman please forgive my confusion. I saw that this library can create shared modules. But I didn't know that it won't work on windows. My wish is to close the task as soon as possible and, if possible, help the ziglua library become better. Of all the libraries, it has the coolest functionality. Now, thanks to you, I have one of the solutions to the task, but it is not as beautiful as your wrapper on zig. I would like to fully use ziglua.

What you did should already work, and I know it should work, but I don't understand what the problem is with windows.

@natecraddock

You have your own copy of Lua 5.4.1 that you have compiled. You want to use Ziglua with this version of lua and build a shared module?

I am far from system programming and will try to explain as best I can.

In general "yes", and here are some details:

  • external product embedded lua version 5.4.1 and gave lua54.dll, and nothing more. This is enough to write lua scripts, but not shared modules in the form of dll
  • to make a dll for a lua script (to extend lua functionality), you need to specify that my shared-dll uses lua54.dll to work. And for this i need to compile the lua sources 5.4.1 to get the lua54.lib file. I don't know about 5.4.7, need test.
  • In a way that is not clear to me, you are forcing shared modules to link lua.dll, which you create yourself. This looks like what I need, except for the name lua.dll
    .name = "lua",
    , which will not work in an external product, they only have filename lua54.dll without the possibility of renaming

If I can solve this problem with ziglua, I will be able to:
hide lua source code compilation from view;
hide lua_ luaL_ functions from view;
use the entire zig ecosystem

@yiv1
Copy link
Author

yiv1 commented Apr 20, 2025

Probably the reason is that mingw gets into the dll

lua54.dll
             1800277A8 Import Address Table
             1800276B0 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                           0 _GetPEImageBase
                           0 __main
                           0 __mingw_GetSectionCount
                           0 __mingw_GetSectionForAddress
                           0 __mingw_TLScallback
                           0 luaL_checkversion_
                           0 luaL_setfuncs
                           0 lua_createtable
                           0 lua_pushinteger
                           0 lua_tointegerx

These methods are not present in the working dll:
0 _GetPEImageBase
0 __main
0 __mingw_GetSectionCount
0 __mingw_GetSectionForAddress
0 __mingw_TLScallback

The working *.lib build does not contain any mingw references. But zig *.lib contains mingw methods.

Changing one line affects the functionality of the dll

libraryLua.addObjectFile(b.path("./src/lua-5.4.1/lua54.lib"));
libraryLua.addObjectFile(b.path("./zig-out/lib/lua54.lib"));

Maybe this will fix the problem. My knowledge is not enough to figure it out, but I will try.

@yiv1
Copy link
Author

yiv1 commented Apr 20, 2025

So, part of the problem is solved. This is not a problem WinGW. Lua developers have already solved it.

Just add flag for .windows if shared

"-DLUA_BUILD_AS_DLL",

If you add an additional flag, I can check if 5.4.7 is compatible with 5.4.1.

Also, the task of linking to lua54.dll (not for lua.dll) is relevant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants