lua 5.3 glue srlua/wsrlua console/windows
基于srlua-vc。
- 项目已配置VS solution
- 针对lua54
- 包含上下文项目lua54、srglue-vc、srlua-vc
- VS打开"srlua-vc.sln","新建解决方案配置"
- 可基于"release"解决方案配置新建。
"srglue-vc"、"srlua-vc"需一起"生成"(尝试不可其他srglue搭配此srlua-vc)(当前期望针对lua53,故无需lua54)(lua53可从luabinaries获取,无需本地生成)
针对新建解决方案,于项目srlua属性页
3. VC++目录+包含目录 库目录,添加"包含目录"、"库目录"
链接器-输入-附加依赖项,修改lua54.lib为lua53.lib
4. "链接器-系统-子系统",修改"控制台"为"窗口"
"链接器-高级-入口点",修改为"mainCRTStartUP"(而非mainWin)(子系统为"控制台"时,缺省默认对应"main")
更改源码:
基于针对"控制台"的"main",更改为"winMain"。
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow) {
// 获取完整命令行
LPSTR cmdLine = GetCommandLineA();
// 解析为 argc/argv
int argc;
char** argv = CommandLineToArgvA(cmdLine, &argc);
lua_State* L = luaL_newstate();
if (L == NULL)
fatal("cannot create state: not enough memory");
lua_pushcfunction(L, msghandler);
lua_pushcfunction(L, &pmain);
lua_pushinteger(L, argc);
lua_pushlightuserdata(L, argv);
if (lua_pcall(L, 2, 0, 1) != 0)
fatal(lua_tostring(L, -1));
lua_close(L);
LocalFree(argv);
return EXIT_SUCCESS;
}
其中"CommandLineToArgvA"来自CommandLineToArgvA
#include <Windows.h>
#include <assert.h>
LPSTR* CommandLineToArgvA(LPSTR lpCmdLine, INT* pNumArgs)
{
int retval;
retval = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpCmdLine, -1, NULL, 0);
if (!SUCCEEDED(retval))
return NULL;
LPWSTR lpWideCharStr = (LPWSTR)malloc(retval * sizeof(WCHAR));
if (lpWideCharStr == NULL)
return NULL;
retval = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, lpCmdLine, -1, lpWideCharStr, retval);
if (!SUCCEEDED(retval))
{
free(lpWideCharStr);
return NULL;
}
int numArgs;
LPWSTR* args;
args = CommandLineToArgvW(lpWideCharStr, &numArgs);
free(lpWideCharStr);
if (args == NULL)
return NULL;
int storage = numArgs * sizeof(LPSTR);
for (int i = 0; i < numArgs; ++i)
{
BOOL lpUsedDefaultChar = FALSE;
retval = WideCharToMultiByte(CP_ACP, 0, args[i], -1, NULL, 0, NULL, &lpUsedDefaultChar);
if (!SUCCEEDED(retval))
{
LocalFree(args);
return NULL;
}
storage += retval;
}
LPSTR* result = (LPSTR*)LocalAlloc(LMEM_FIXED, storage);
if (result == NULL)
{
LocalFree(args);
return NULL;
}
int bufLen = storage - numArgs * sizeof(LPSTR);
LPSTR buffer = ((LPSTR)result) + numArgs * sizeof(LPSTR);
for (int i = 0; i < numArgs; ++i)
{
assert(bufLen > 0);
BOOL lpUsedDefaultChar = FALSE;
retval = WideCharToMultiByte(CP_ACP, 0, args[i], -1, buffer, bufLen, NULL, &lpUsedDefaultChar);
if (!SUCCEEDED(retval))
{
LocalFree(result);
LocalFree(args);
return NULL;
}
result[i] = buffer;
buffer += retval;
bufLen -= retval;
}
LocalFree(args);
*pNumArgs = numArgs;
return result;
}
关于传入程序路径、命令行参数,可参考:
参考:
- Is there the CommandLineToArgvA function in windows c/c++ (VS 2022)
有Antonio Scuri借鉴wlua.exe、lua.exe描述srlua.exe(与wsrlua)。