视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
No2:luacom中文内容输出BUG及修正
2020-11-09 07:36:29 责编:小采
文档


使 用cell.Value2输出中文内容时总是乱码。怀疑是utf-8的原因,转换后结果仍然是乱码。自己再写个转换的再测试,依然是乱码,莫非有BUG!? 下个LUACOM的源码,查看函数 tLuaCOMTypeHandler::com2lua 和 tStringBuffer tUtil::bstr2string 。整个过程看起来

使用cell.Value2输出中文内容时总是乱码。怀疑是utf-8的原因,转换后结果仍然是乱码。自己再写个转换的再测试,依然是乱码,莫非有BUG!?

下个LUACOM的源码,查看函数tLuaCOMTypeHandler::com2lua和tStringBuffer tUtil::bstr2string。整个过程看起来都OK,但再测试发现,结果字符串少了一个bytes。

在tLuaCOMTypeHandler::com2lua VT_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" {
#include "lua.h"
#include "lualib.h" 
#include "lauxlib.h"
int luaopen_local(lua_State* L);
}

#include 
#include 
#ifdef WIN32
#include 
#include 
#else
#include 
#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();
	for (int i=0; i0) {
	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;
}

下载本文
显示全文
专题