LuaPanda
LuaPanda copied to clipboard
lua5.4 or lua JIT中文lua编程(中文变量,中文函数,中文lua文件名)最佳实践
首先,lua5.4 or lua JIT 宏定义LUA_UCID后是可以支持中文变量,函数
(这条存疑)如果vscode显示文件名不为乱码不用修改 修改LuaPanda.lua取路径函数,处理输入gbk编码时vscode显示文件名为乱码问题
function this.getPath( info ) 在函数最后三行,加入编码转换filePath = GbkToUtf8(filePath)
filePath = GbkToUtf8(filePath)
--放入Cache中缓存
this.setCacheFormatPath(originalPath, filePath);
print("filePath " .. filePath)
return filePath;
end
//使用sol2进行函数绑定
lua.set_function(u8"GbkToUtf8", [](const std::string& gbkStr) -> std::string {
return 字符串::GbkToUtf8(gbkStr);
});
export std::string GbkToUtf8(std::string src_str)
{
int len = MultiByteToWideChar(CP_ACP, 0, src_str.c_str(), -1, NULL, 0);
wchar_t* wstr = new wchar_t[len + 1];
memset(wstr, 0, len + 1);
MultiByteToWideChar(CP_ACP, 0, src_str.c_str(), -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len + 1];
memset(str, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
std::string strTemp = str;
if (wstr) delete[] wstr;
if (str) delete[] str;
return strTemp;
}
解决使用utf8编写lua代码时,使用require()导入中文文件时,utf8编码转换问题 例子 require("测试.测试.测试2") 修改lua源码loadlib.c文件 ll_require函数实现
char* UTF8_to_ANSI(const char* utf8_string) {
if (!utf8_string) return NULL;
// 1. Convert UTF-8 to UTF-16 (WideChar)
// Get the required buffer size for UTF-16 string (including null terminator)
int wide_chars_len = MultiByteToWideChar(CP_UTF8, 0, utf8_string, -1, NULL, 0);
if (wide_chars_len == 0) {
// MultiByteToWideChar failed (e.g., invalid UTF-8)
// You could check GetLastError() for more details.
return NULL;
}
wchar_t* wide_buffer = (wchar_t*)malloc(wide_chars_len * sizeof(wchar_t));
if (!wide_buffer) {
return NULL; // Allocation failed
}
// Perform the conversion from UTF-8 to UTF-16
int result = MultiByteToWideChar(CP_UTF8, 0, utf8_string, -1, wide_buffer, wide_chars_len);
if (result == 0) {
// Conversion failed
free(wide_buffer);
return NULL;
}
// 2. Convert UTF-16 to ANSI (CP_ACP - system default ANSI code page)
// Get the required buffer size for ANSI string (including null terminator)
int ansi_chars_len = WideCharToMultiByte(CP_ACP, 0, wide_buffer, wide_chars_len, NULL, 0, NULL, NULL);
if (ansi_chars_len == 0) {
// WideCharToMultiByte failed (e.g., no mapping for some characters)
free(wide_buffer);
return NULL;
}
char* ansi_buffer = (char*)malloc(ansi_chars_len * sizeof(char));
if (!ansi_buffer) {
free(wide_buffer);
return NULL; // Allocation failed
}
// Perform the conversion from UTF-16 to ANSI
result = WideCharToMultiByte(CP_ACP, 0, wide_buffer, wide_chars_len, ansi_buffer, ansi_chars_len, NULL, NULL);
if (result == 0) {
// Conversion failed
free(wide_buffer);
free(ansi_buffer);
return NULL;
}
free(wide_buffer); // Free the intermediate UTF-16 buffer
return ansi_buffer; // Return the dynamically allocated ANSI string
// Caller is responsible for freeing this memory using free()
}
static int ll_require(lua_State* L) {
const char* name = luaL_checkstring(L, 1);
char* name_ansi = UTF8_to_ANSI(name);
if (name_ansi == NULL) {
// Conversion failed (e.g., invalid UTF-8 or character mapping issues)
// Use luaL_error to report the error back to Lua. It does not return.
// The memory for name_ansi is NULL, so no need to free.
luaL_error(L, "Failed to convert module name '%s' to ANSI for loading", name);
}
lua_settop(L, 1); /* LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
lua_getfield(L, 2, name); /* LOADED[name] */
if (lua_toboolean(L, -1)) /* is it there? */
return 1; /* package is already loaded */
/* else must load package */
lua_pop(L, 1); /* remove 'getfield' result */
findloader(L, name_ansi);
free(name_ansi);
lua_rotate(L, -2, 1); /* function <-> loader data */
lua_pushvalue(L, 1); /* name is 1st argument to module loader */
lua_pushvalue(L, -3); /* loader data is 2nd argument */
/* stack: ...; loader data; loader function; mod. name; loader data */
lua_call(L, 2, 1); /* run loader to load module */
/* stack: ...; loader data; result from loader */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* LOADED[name] = returned value */
else
lua_pop(L, 1); /* pop nil */
if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
lua_pushboolean(L, 1); /* use true as result */
lua_copy(L, -1, -2); /* replace loader result */
lua_setfield(L, 2, name); /* LOADED[name] = true */
}
lua_rotate(L, -2, 1); /* loader data <-> module result */
return 2; /* return module result and loader data */
}
展示成果,变量 函数 堆栈都已经可以正确显示