LuaPanda icon indicating copy to clipboard operation
LuaPanda copied to clipboard

lua5.4 or lua JIT中文lua编程(中文变量,中文函数,中文lua文件名)最佳实践

Open qqq694637644 opened this issue 9 months ago • 2 comments

首先,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;
	}

qqq694637644 avatar Apr 24 '25 05:04 qqq694637644

解决使用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 */
}

qqq694637644 avatar Apr 24 '25 05:04 qqq694637644

展示成果,变量 函数 堆栈都已经可以正确显示 Image

Image

qqq694637644 avatar Apr 24 '25 05:04 qqq694637644