[script] How to compile a lua library from C?

How to compile a lua library that is compatible with SV?

I have a .c code and I’m trying to compile it into a .dll library, then require it in my lua scripts for SV.

Currently there’s no difficulty in requiring. Simply put any .lua or .dll under the same directory where your synthv-studio.exe is located, and scripts will be able to require them. (See this post for reference.)

I can compile the code using pre-compiled dev packs from lua’s official download, but the result is not compatible with SV, giving an “error loading module” error. I suspect it’s due to the mismatch of compiler versions between my compiled dll and SV’s lua core. I just tried one among the 4 different compiler versions provided by the official download. But I don’t really want to mess more with multiple compiler versions on my laptop, and I’m not even sure if SV’s lua core is compiled by one of these compilers.

So does anybody have any clue about this? And it will be very nice if you’d like to test out those 4 compilers. Of course, it would be the best if SV developers pop up and reveal some information or improve their scripting system (there’re so many feature requests about scripting but sadly none of them are answered), but I can hardly expect that to happen.

Also I may have missed something since I’m quite new to lua. Do you have any related experience?

How to support utf-8 filenames?

In particular, I’m trying to patch @hataori’s Real Voice scripts to support utf-8 filenames (which is really an important QoL issue when making Japanese or Chinese songs etc., and does have been requested by a few people). (Also a shout-out to Real Voice scripts!)

It’s a rather intrinsic issue because lua doesn’t care about encoding (because of lua’s philosophy of simplicity) and that lua sticks to ANSI C APIs, among which functions like fopen are very poor with utf-8. Solutions I found are either modifying lua core like lua-unicode (obviously not a viable way for us), or writing a C module like luawinfile. So I choose the latter and use something like

if package.config:sub(1,1) ~= '/' then	-- check if it's Windows
	local winfile = require("winfile")
	io.open = winfile.open
end

So here I am, trying to compile this winfile.c into winfile.dll to use in SV scripts.

If you have any ideas on how to support utf-8 filenames, it would be very very nice and can solve all these problems!

And I’m also happy to discuss anything related to scripting in this thread.

Most versions of Lua include utf-8 support. Unfortunately, SynthV handy, so I can’t test it.

Someone brought up this sort of question for Kontakt, so I ended up going down that rabbit hole.

As you noted, it’s not pretty because Lua uses C functions, which only handle single-byte text. Even with the Unicode support, calls to system functions will normally call core C functions that only have single-byte support.

There’s a way that file names can he handled in Windows, but there’s a big catch: you have to specify the codepage that you want to use. So you don’t have access to all Unicode characters, just those in the locale that you specify.

See: UTF-8 filenames on Windows in pure Lua · GitHub

This also: Lua: how to make os.rename & os.remove work with filenames containing unicode characters? - Stack Overflow

「いいね!」 2

It is the same with creating a general FFI module.
I’ve already succeeded in building in Windows, but Mac (Arm) has an issue with the build.
So, I don’t want to recommend it

I don’t remember well because I studied it a long time ago, but I’ll share the code I used.

For the location of DLL, I recommend the location of the synthv.exe file.

As a caution, the DLL could not be imported intermittently, and there was an error when trying to import twice.

Linux C++

#ifdef _cplusplus
extern "C" {
#endif

#include <lua5.4/lua.h>
#include <lua5.4/lualib.h>
#include <lua5.4/lauxlib.h>

#ifdef _cplusplus
}
#endif

int test_add1(lua_State* L) {
        double d = luaL_checknumber(L, 1);
        lua_pushnumber(L, d+1);
        return 1;
}

static const struct luaL_Reg testlib[] = {
        {"add1", test_add1},
        {NULL, NULL}
};

extern "C"
int luaopen_test(lua_State* L){
        lua_register(L, "test", test_add1);
        return 1;
}

Build in Linux

g++ test.cpp -shared -fpic -I/usr/include -o test.so

Lua test

require("test")
print(test)
test(1)

Windows dll project (Visual studio)

#include "pch.h"

#include <lua.hpp>

extern "C" {
    int libtest_cAdd(lua_State* L) {
        double n1 = luaL_checknumber(L, 1);
        double n2 = luaL_checknumber(L, 2);
        double sum = n1 + n2;
        lua_pushnumber(L, sum);
        return 1;
    }

    static const luaL_Reg mylib[] = {
            {"cAdd", libtest_cAdd},
            {NULL, NULL}
    };


    __declspec(dllexport) int luaopen_testlua(lua_State* L) {
        luaL_newlib(L, mylib);
        return 1;
    }
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

test 2

luatest = require('testlua')
luatest.cAdd(1, 2)
「いいね!」 3