After checking, luacom has no problem, it is the code of lc conversion has problem, did not notice that lua_tolstring will contain one more space, resulting in luacom is considered to have one fewer space (add up 2 spaces to exactly end 2 characters), the idea is completely wrong, the following is obsolete.
cell.Value2 is always garbled when it is used to output Chinese content.The reason for utf-8 is suspected, and the result remains garbled after conversion.Write another conversion yourself test Still a mess, BUG!?
Next source for LUACOM, look at the functions tLuaCOMTypeHandler::com2lua and tStringBuffer tUtil::bstr2string.The whole process looks OK, but another test found that the result string is one bytes less.
The result returned in the tLuaCOMTypeHandler::com2luaVT_BSTR branch is exactly minus 1, modifying it
lua_pushlstring(L, str, str.getSize()-1); modified to lua_pushlstring(L, str, str.getSize());
Recompile LUACOM and look at the cell.Value2 output, and it's finally correct.It is not known if this modification will introduce errors because it has not been fully tested. Resources There is one that has been compiled.
--lc is a unicode utf-8 ansi conversion function copied from the Internet
- package.cpath=[[C:\Program Files\Lua\5.1\clibs\?.dll;d:\loonlib\sample\lc\?.dll]]
- require "luacom"
- require "lc"
- function print_table(t) for k,v in pairs(t) do print(k,v) end end
- excel = luacom.CreateObject("Excel.Application")
- excel.Visible = true
- excel.Workbooks:Add();
- --luacom.ViewTypeLib(excel);
- sheet=excel.Sheets(1);
- local r=sheet:Range("E6");
- local s = "Yanzhong";
- ws, s2=lc.a2w(s); --0x25 0x4e 0x2d 0x4e 0x00 0x00 6
- print("unicode : " .. lc.bstr(ws, s2));
- us, s2=lc.w2u(ws, s2); --0xe4 0xb8 0xa5 0xe4 0xb8 0xad 0x00 0x00 8
- print("utf8 : " .. lc.bstr(us, s2));
- r.Value2=us;
- ws, s2=lc.u2w(r.Value2, s2);
- print("unicode : " .. lc.bstr(ws, s2));
- as, s2=lc.w2a(ws, s2);
- print("ansi : " .. lc.bstr(as, s2));
- print(as);
lc.def
- LIBRARY "lc"
- EXPORTS
- luaopen_lc
lc.h
- extern "C" {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- int luaopen_local(lua_State* L);
- }
- #include <locale.h>
- #include <cstring>
- #ifdef WIN32
- #include <windows.h>
- #include <winnls.h>
- #else
- #include <cstdlib>
- #endif
- #define LN_lc "lc"
- int lua_a2w(lua_State* L);
- int lua_u2w(lua_State* L);
- int lua_w2a(lua_State* L);
- int lua_w2u(lua_State* L);
- int lua_u2a(lua_State* L);
- int lua_a2u(lua_State* L);
- int lua_bstr(lua_State* L);
- int lua_help(lua_State* L);
- wchar_t* mb2wc(const char* mbstr, int& s2, int cp);
- char* wc2mb(const wchar_t* wcstr, int& s2, int cp);
lc.cpp
- #include "lc.h"
- //g++ -shared -s -o lc.dll -O3 lc.cpp lc.def -llua5.1 -DWIN32 -I%loon%/lua/src -L%loon%/lib/gcc_dll/debug -Wl,--out-implib,liblc.a
- int lua_bstr(lua_State* L) {
- const char* s = luaL_optstring(L, 1, "");
- int len = luaL_optnumber(L, 2, 0);
- if (strcmp(s, "")==0 || 0==len) {
- lua_pushstring(L, s);
- } else {
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- char* byte = (char*)malloc(64);
- for (int i=0; i<len; ++i) {
- sprintf(byte, "0x%02x ", (unsigned char)*s++);
- luaL_addstring(&b, byte);
- }
- free(byte);
- luaL_pushresult(&b);
- }
- return 1;
- }
- int lua_u2w(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_UTF8);
- if (wcstr) {
- lua_pushlstring(L, (const char*)wcstr, s2);
- lua_pushnumber(L, s2);
- delete[] wcstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_a2w(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_ACP);
- if (wcstr) {
- lua_pushlstring(L, (const char*)wcstr, s2);
- lua_pushnumber(L, s2);
- delete[] wcstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_w2a(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* wcstr = lua_tolstring(L, 1, &len);
- if (wcstr && len>0) {
- int s2 = 0;
- char* mbstr = wc2mb((wchar_t*)wcstr, s2, CP_ACP);
- if (mbstr) {
- lua_pushlstring(L, mbstr, s2);
- lua_pushnumber(L, s2);
- delete[] mbstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_w2u(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* wcstr = lua_tolstring(L, 1, &len);
- if (wcstr && len>0) {
- int s2 = 0;
- char* mbstr = wc2mb((wchar_t*)wcstr, s2, CP_UTF8);
- if (mbstr) {
- lua_pushlstring(L, mbstr, s2);
- lua_pushnumber(L, s2);
- delete[] mbstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_u2a(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_UTF8);
- if (wcstr) {
- char* nmbstr = wc2mb(wcstr, s2, CP_ACP);
- if (nmbstr) {
- lua_pushlstring(L, nmbstr, s2);
- lua_pushnumber(L, s2);
- result = 2;
- delete[] nmbstr;
- }
- delete[] wcstr;
- }
- }
- return result;
- }
- int lua_a2u(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_ACP);
- if (wcstr) {
- char* nmbstr = wc2mb(wcstr, s2, CP_UTF8);
- if (nmbstr) {
- lua_pushlstring(L, nmbstr, s2);
- lua_pushnumber(L, s2);
- result = 2;
- delete[] nmbstr;
- }
- delete[] wcstr;
- }
- }
- return result;
- }
- wchar_t* mb2wc(const char* mbstr, int& s2, int cp) {
- wchar_t* wcstr = NULL;
- #ifdef WIN32
- int size = MultiByteToWideChar(cp, 0, mbstr, -1, NULL, 0);
- #else
- size_t size = mbstowcs(NULL, mbstr, 0);
- #endif
- wcstr = new wchar_t[size];
- if (wcstr) {
- memset(wcstr, 0, size * sizeof(wchar_t));
- #ifdef WIN32
- int ret = MultiByteToWideChar(cp, 0, mbstr, -1, wcstr, size);
- if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.
- #else
- size_t ret = mbstowcs(wcstr, mbstr, size+1);
- if (ret == -1) {
- #endif
- delete[] wcstr;
- wcstr = NULL;
- }
- s2 = 2*size;
- }
- return wcstr;
- }
- char* wc2mb(const wchar_t* wcstr, int& s2, int cp) {
- char* mbstr = NULL;
- #ifdef WIN32
- int size = WideCharToMultiByte(cp, 0, wcstr, -1, NULL, 0, NULL, NULL);
- #else
- size_t size = wcstombs(NULL, wcstr, 0);
- #endif
- mbstr = new char[size];
- if (mbstr) {
- memset(mbstr, 0, size * sizeof(char));
- #ifdef WIN32
- int ret = WideCharToMultiByte(cp, 0, wcstr, -1, mbstr, size, NULL, NULL);
- if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.
- #else
- size_t ret = wcstombs(mbstr, wcstr, size+1);
- if (ret == -1) {
- #endif
- delete[] mbstr;
- mbstr = NULL;
- }
- s2 = size;
- }
- return mbstr;
- }
- int lua_help(lua_State* L) {
- const char* s=
- "Simple Characters Transformation\n"
- " a2w(ansi to unicode)\n"
- " u2w(utf8 to unicode)\n"
- " w2a(unicode to ansi)\n"
- " w2u(unicode to utf8)\n"
- " u2a(utf8 to ansi)\n"
- " a2u(ansi to utf8)\n"
- " bstr(bytes of str)\n"
- " help(show this)\n\n"
- " example :\n"
- " local s = \"I like lua\"\n"
- " print(lc.bstr(s, string.len(s)+1))\n"
- " local ws, s2 = lc.a2w(s)\n"
- "wunoman@qq.com 2012/03/06\n"
- ;
- lua_pushstring(L, s);
- return 1;
- }
- luaL_reg lrg_lc[] = {
- {"a2w", lua_a2w},
- {"u2w", lua_u2w},
- {"w2a", lua_w2a},
- {"w2u", lua_w2u},
- {"u2a", lua_u2a},
- {"a2u", lua_a2u},
- {"bstr", lua_bstr},
- {"help", lua_help},
- {NULL, NULL}
- };
- extern "C" int luaopen_lc(lua_State* L) {
- luaL_register(L, LN_lc, lrg_lc);
- return 1;
- }
After checking, luacom has no problem, it is the code of lc conversion has problem, did not notice that lua_tolstring will contain one more space, resulting in luacom is considered to have one less space (add up 2 spaces to exactly end 2 characters), the idea is completely wrong, and will be discarded below.
cell.Value2 is always garbled when it is used to output Chinese content.The reason for utf-8 is suspected, and the result remains garbled after conversion.Write another conversion yourself test Still a mess, BUG!?
Next source for LUACOM, look at the functions tLuaCOMTypeHandler::com2lua and tStringBuffer tUtil::bstr2string.The whole process looks OK, but another test found that the result string is one bytes less.
The result returned in the tLuaCOMTypeHandler::com2luaVT_BSTR branch is exactly minus 1, modifying it
lua_pushlstring(L, str, str.getSize()-1); modified to lua_pushlstring(L, str, str.getSize());
Recompile LUACOM and look at the cell.Value2 output, and it's finally correct.It is not known if this modification will introduce errors because it has not been fully tested. Resources There is one that has been compiled.
--lc is a unicode utf-8 ansi conversion function copied from the Internet
- package.cpath=[[C:\Program Files\Lua\5.1\clibs\?.dll;d:\loonlib\sample\lc\?.dll]]
- require "luacom"
- require "lc"
- function print_table(t) for k,v in pairs(t) do print(k,v) end end
- excel = luacom.CreateObject("Excel.Application")
- excel.Visible = true
- excel.Workbooks:Add();
- --luacom.ViewTypeLib(excel);
- sheet=excel.Sheets(1);
- local r=sheet:Range("E6");
- local s = "Yanzhong";
- ws, s2=lc.a2w(s); --0x25 0x4e 0x2d 0x4e 0x00 0x00 6
- print("unicode : " .. lc.bstr(ws, s2));
- us, s2=lc.w2u(ws, s2); --0xe4 0xb8 0xa5 0xe4 0xb8 0xad 0x00 0x00 8
- print("utf8 : " .. lc.bstr(us, s2));
- r.Value2=us;
- ws, s2=lc.u2w(r.Value2, s2);
- print("unicode : " .. lc.bstr(ws, s2));
- as, s2=lc.w2a(ws, s2);
- print("ansi : " .. lc.bstr(as, s2));
- print(as);
lc.def
- LIBRARY "lc"
- EXPORTS
- luaopen_lc
lc.h
- extern "C" {
- #include "lua.h"
- #include "lualib.h"
- #include "lauxlib.h"
- int luaopen_local(lua_State* L);
- }
- #include <locale.h>
- #include <cstring>
- #ifdef WIN32
- #include <windows.h>
- #include <winnls.h>
- #else
- #include <cstdlib>
- #endif
- #define LN_lc "lc"
- int lua_a2w(lua_State* L);
- int lua_u2w(lua_State* L);
- int lua_w2a(lua_State* L);
- int lua_w2u(lua_State* L);
- int lua_u2a(lua_State* L);
- int lua_a2u(lua_State* L);
- int lua_bstr(lua_State* L);
- int lua_help(lua_State* L);
- wchar_t* mb2wc(const char* mbstr, int& s2, int cp);
- char* wc2mb(const wchar_t* wcstr, int& s2, int cp);
lc.cpp
- #include "lc.h"
- //g++ -shared -s -o lc.dll -O3 lc.cpp lc.def -llua5.1 -DWIN32 -I%loon%/lua/src -L%loon%/lib/gcc_dll/debug -Wl,--out-implib,liblc.a
- int lua_bstr(lua_State* L) {
- const char* s = luaL_optstring(L, 1, "");
- int len = luaL_optnumber(L, 2, 0);
- if (strcmp(s, "")==0 || 0==len) {
- lua_pushstring(L, s);
- } else {
- luaL_Buffer b;
- luaL_buffinit(L, &b);
- char* byte = (char*)malloc(64);
- for (int i=0; i<len; ++i) {
- sprintf(byte, "0x%02x ", (unsigned char)*s++);
- luaL_addstring(&b, byte);
- }
- free(byte);
- luaL_pushresult(&b);
- }
- return 1;
- }
- int lua_u2w(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_UTF8);
- if (wcstr) {
- lua_pushlstring(L, (const char*)wcstr, s2);
- lua_pushnumber(L, s2);
- delete[] wcstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_a2w(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_ACP);
- if (wcstr) {
- lua_pushlstring(L, (const char*)wcstr, s2);
- lua_pushnumber(L, s2);
- delete[] wcstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_w2a(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* wcstr = lua_tolstring(L, 1, &len);
- if (wcstr && len>0) {
- int s2 = 0;
- char* mbstr = wc2mb((wchar_t*)wcstr, s2, CP_ACP);
- if (mbstr) {
- lua_pushlstring(L, mbstr, s2);
- lua_pushnumber(L, s2);
- delete[] mbstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_w2u(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* wcstr = lua_tolstring(L, 1, &len);
- if (wcstr && len>0) {
- int s2 = 0;
- char* mbstr = wc2mb((wchar_t*)wcstr, s2, CP_UTF8);
- if (mbstr) {
- lua_pushlstring(L, mbstr, s2);
- lua_pushnumber(L, s2);
- delete[] mbstr;
- result = 2;
- }
- }
- return result;
- }
- int lua_u2a(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_UTF8);
- if (wcstr) {
- char* nmbstr = wc2mb(wcstr, s2, CP_ACP);
- if (nmbstr) {
- lua_pushlstring(L, nmbstr, s2);
- lua_pushnumber(L, s2);
- result = 2;
- delete[] nmbstr;
- }
- delete[] wcstr;
- }
- }
- return result;
- }
- int lua_a2u(lua_State* L) {
- int result = 0;
- size_t len = 0;
- const char* mbstr = lua_tolstring(L, 1, &len);
- if (mbstr && len>0) {
- int s2 = 0;
- wchar_t* wcstr = mb2wc(mbstr, s2, CP_ACP);
- if (wcstr) {
- char* nmbstr = wc2mb(wcstr, s2, CP_UTF8);
- if (nmbstr) {
- lua_pushlstring(L, nmbstr, s2);
- lua_pushnumber(L, s2);
- result = 2;
- delete[] nmbstr;
- }
- delete[] wcstr;
- }
- }
- return result;
- }
- wchar_t* mb2wc(const char* mbstr, int& s2, int cp) {
- wchar_t* wcstr = NULL;
- #ifdef WIN32
- int size = MultiByteToWideChar(cp, 0, mbstr, -1, NULL, 0);
- #else
- size_t size = mbstowcs(NULL, mbstr, 0);
- #endif
- wcstr = new wchar_t[size];
- if (wcstr) {
- memset(wcstr, 0, size * sizeof(wchar_t));
- #ifdef WIN32
- int ret = MultiByteToWideChar(cp, 0, mbstr, -1, wcstr, size);
- if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.
- #else
- size_t ret = mbstowcs(wcstr, mbstr, size+1);
- if (ret == -1) {
- #endif
- delete[] wcstr;
- wcstr = NULL;
- }
- s2 = 2*size;
- }
- return wcstr;
- }
- char* wc2mb(const wchar_t* wcstr, int& s2, int cp) {
- char* mbstr = NULL;
- #ifdef WIN32
- int size = WideCharToMultiByte(cp, 0, wcstr, -1, NULL, 0, NULL, NULL);
- #else
- size_t size = wcstombs(NULL, wcstr, 0);
- #endif
- mbstr = new char[size];
- if (mbstr) {
- memset(mbstr, 0, size * sizeof(char));
- #ifdef WIN32
- int ret = WideCharToMultiByte(cp, 0, wcstr, -1, mbstr, size, NULL, NULL);
- if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.
- #else
- size_t ret = wcstombs(mbstr, wcstr, size+1);
- if (ret == -1) {
- #endif
- delete[] mbstr;
- mbstr = NULL;
- }
- s2 = size;
- }
- return mbstr;
- }
- int lua_help(lua_State* L) {
- const char* s=
- "Simple Characters Transformation\n"
- " a2w(ansi to unicode)\n"
- " u2w(utf8 to unicode)\n"
- " w2a(unicode to ansi)\n"
- " w2u(unicode to utf8)\n"
- " u2a(utf8 to ansi)\n"
- " a2u(ansi to utf8)\n"
- " bstr(bytes of str)\n"
- " help(show this)\n\n"
- " example :\n"
- " local s = \"I like lua\"\n"
- " print(lc.bstr(s, string.len(s)+1))\n"
- " local ws, s2 = lc.a2w(s)\n"
- "wunoman@qq.com 2012/03/06\n"
- ;
- lua_pushstring(L, s);
- return 1;
- }
- luaL_reg lrg_lc[] = {
- {"a2w", lua_a2w},
- {"u2w", lua_u2w},
- {"w2a", lua_w2a},
- {"w2u", lua_w2u},
- {"u2a", lua_u2a},
- {"a2u", lua_a2u},
- {"bstr", lua_bstr},
- {"help", lua_help},
- {NULL, NULL}
- };
- extern "C" int luaopen_lc(lua_State* L) {
- luaL_register(L, LN_lc, lrg_lc);
- return 1;
- }
Reprinted at: https://www.cnblogs.com/codingking/p/6491091.html