经检查,luacom没有问题,是lc转换的代码有问题,没有注意到lua_tolstring都会包含一个结束符造成多了一个空格,导致认为是luacom少了一个空格(加起来2个空格刚好是2个字符的结束符),思路完全错误,下文作废。
 
使用cell.Value2输出中文内容时总是乱码。怀疑是utf-8的原因,转换后结果仍然是乱码。自己再写个转换的再测试,依然是乱码,莫非有BUG!?
下个LUACOM的源码,查看函数tLuaCOMTypeHandler::com2lua和tStringBuffer tUtil::bstr2string。整个过程看起来都OK,但再测试发现,结果字符串少了一个bytes。
    在tLuaCOMTypeHandler::com2luaVT_BSTR分支中返回结果恰好是减去1,将其修改
lua_pushlstring(L, str, str.getSize()-1);修改为lua_pushlstring(L, str, str.getSize());
    重新编译LUACOM,再看cell.Value2输出结果,终于正确了。由于没进行全面测试,不知道其此修改会不会引入错误。资源里有个已经编译好的。
--lc是从网上抄来的unicode utf-8 ansi相互转换的函数
 
- 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 = "严中";  
- 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" {  
-   
-   
-   
- int luaopen_local(lua_State* L);  
- }  
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
- 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
 
-   
- //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;  
-   
-     int size = MultiByteToWideChar(cp, 0, mbstr, -1, NULL, 0);  
-   
-     size_t size = mbstowcs(NULL, mbstr, 0);  
-   
-     wcstr = new wchar_t[size];  
-     if (wcstr) {  
-         memset(wcstr, 0, size * sizeof(wchar_t));  
-   
-         int ret = MultiByteToWideChar(cp, 0, mbstr, -1, wcstr, size);  
-         if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.  
-   
-         size_t ret = mbstowcs(wcstr, mbstr, size+1);  
-         if (ret == -1) {  
-   
-             delete[] wcstr;  
-             wcstr = NULL;  
-         }  
-         s2 = 2*size;  
-     }  
-     return wcstr;  
- }  
-   
- char* wc2mb(const wchar_t* wcstr, int& s2, int cp) {  
-     char* mbstr = NULL;  
-   
-     int size = WideCharToMultiByte(cp, 0, wcstr, -1, NULL, 0, NULL, NULL);  
-   
-     size_t size = wcstombs(NULL, wcstr, 0);  
-   
-     mbstr = new char[size];  
-     if (mbstr) {  
-         memset(mbstr, 0, size * sizeof(char));  
-   
-         int ret = WideCharToMultiByte(cp, 0, wcstr, -1, mbstr, size, NULL, NULL);  
-         if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.  
-   
-         size_t ret = wcstombs(mbstr, wcstr, size+1);  
-         if (ret == -1) {  
-   
-             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;  
- }  
 
 经检查,luacom没有问题,是lc转换的代码有问题,没有注意到lua_tolstring都会包含一个结束符造成多了一个空格,导致认为是luacom少了一个空格(加起来2个空格刚好是2个字符的结束符),思路完全错误,下文作废。
 
使用cell.Value2输出中文内容时总是乱码。怀疑是utf-8的原因,转换后结果仍然是乱码。自己再写个转换的再测试,依然是乱码,莫非有BUG!?
下个LUACOM的源码,查看函数tLuaCOMTypeHandler::com2lua和tStringBuffer tUtil::bstr2string。整个过程看起来都OK,但再测试发现,结果字符串少了一个bytes。
    在tLuaCOMTypeHandler::com2luaVT_BSTR分支中返回结果恰好是减去1,将其修改
lua_pushlstring(L, str, str.getSize()-1);修改为lua_pushlstring(L, str, str.getSize());
    重新编译LUACOM,再看cell.Value2输出结果,终于正确了。由于没进行全面测试,不知道其此修改会不会引入错误。资源里有个已经编译好的。
--lc是从网上抄来的unicode utf-8 ansi相互转换的函数
 
- 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 = "严中";  
- 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" {  
-   
-   
-   
- int luaopen_local(lua_State* L);  
- }  
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
- 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
 
-   
- //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;  
-   
-     int size = MultiByteToWideChar(cp, 0, mbstr, -1, NULL, 0);  
-   
-     size_t size = mbstowcs(NULL, mbstr, 0);  
-   
-     wcstr = new wchar_t[size];  
-     if (wcstr) {  
-         memset(wcstr, 0, size * sizeof(wchar_t));  
-   
-         int ret = MultiByteToWideChar(cp, 0, mbstr, -1, wcstr, size);  
-         if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.  
-   
-         size_t ret = mbstowcs(wcstr, mbstr, size+1);  
-         if (ret == -1) {  
-   
-             delete[] wcstr;  
-             wcstr = NULL;  
-         }  
-         s2 = 2*size;  
-     }  
-     return wcstr;  
- }  
-   
- char* wc2mb(const wchar_t* wcstr, int& s2, int cp) {  
-     char* mbstr = NULL;  
-   
-     int size = WideCharToMultiByte(cp, 0, wcstr, -1, NULL, 0, NULL, NULL);  
-   
-     size_t size = wcstombs(NULL, wcstr, 0);  
-   
-     mbstr = new char[size];  
-     if (mbstr) {  
-         memset(mbstr, 0, size * sizeof(char));  
-   
-         int ret = WideCharToMultiByte(cp, 0, wcstr, -1, mbstr, size, NULL, NULL);  
-         if (ret == 0) { // MultiByteToWideChar returns 0 if it does not succeed.  
-   
-         size_t ret = wcstombs(mbstr, wcstr, size+1);  
-         if (ret == -1) {  
-   
-             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;  
- }  
 No2:luacom中文内容输出BUG及修正
原文:http://www.cnblogs.com/codingking/p/6491091.html