您的位置:首页 > 其它

使用STRINGN_TO_NPVARIANT和STRINGZ_TO_NPVARIANT 注意的事项

2014-09-24 12:51 579 查看
一、STRINGZ_TO_NPVARIANT 输出

如果大家不小心的话,直接使用下面的方式输出

STRINGZ_TO_NPVARIANT("test", *result);

STRINGZ_TO_NPVARIANT(strdup("test"), *result);

则都会得不到预期的结果,要么web页面直接崩溃,要么web调用页面无法正常显示。原因是插件在处理输出的时候,如果是字符串,必须NPN_MemAlloc来分配一个内存,用于在浏览器内存空间保存插件的返回值,注意其他的分配方式都是不对的,比如malloc。

所以正确的使用方式如下:

char m_szText[]
= "test";

int len = strlen(m_szText)+1;

NPUTF8 *utf8_chars = static_cast<NPUTF8 *>(NPN_MemAlloc(len));

memset( utf8_chars, 0, len );

strncpy( utf8_chars, m_szText, len);

STRINGZ_TO_NPVARIANT(utf8_chars, *result);

二、字符编码

从上面的例子我们可以看到,在返回字符串给js代码时,一般都是采用utf8编码,这也是为了跟html页面匹配,因为html页面默认也是uft8.



三、STRINGZ_TO_NPVARIANT与STRINGN_TO_NPVARIANT的区别

把字符串返回给js调用时,NPAPI提供了两个方法,下面先看下他们的定义说明:

STRINGZ_TO_NPVARIANT()


Initialize
v
to a variant of type
NPVariantType_String
with
the value being an
NPString
holding
the UTF-8 string value
val
.
STRINGN_TO_NPVARIANT()

Initialize
v
to a variant of type
NPVariantType_String
with
the value being an
NPString
holding
the UTF-8 string value
val
with the length
len
.
意思都是把UTf-8编码的字串返回,只不过STRINGN_TO_NPVARIANT指定了字符串的长度len。下面我们再看下他们的宏定义#define
STRINGZ_TO_NPVARIANT(_val, _v) NP_BEGIN_MACRO (_v).type = NPVariantType_String; NPString str = { _val,strlen(_val)
}; (_v).value.stringValue = str; NP_END_MACRO

#define STRINGN_TO_NPVARIANT(_val, _len, _v) NP_BEGIN_MACRO (_v).type =NPVariantType_String; NPString str = { _val,
_len }; (_v).value.stringValue =str; NP_END_MACRO

看到这里,大家应该就明白了,STRINGZ_TO_NPVARIANT方法是自己在内部使用strlen计算字符串的长度,然后创建新的字串,而STRINGN_TO_NPVARIANT根据传递的参数_len当做字符串的长度,然后创建新的字串,所以_len应该就是strlen计算的字串长度,不包括结束符。

所以上面的事例使用STRINGN_TO_NPVARIANT就是:

STRINGN_TO_NPVARIANT(utf8_chars,
len - 1, *result);

注意这里是len-1,有效字串长度,不是空间大小,如果STRINGN_TO_NPVARIANT(utf8_chars,
len, *result);js得到的字串就会多一些无效字符。

四、中文显示

如果直接返回中文,则中文不会显示,比如:

char m_szText[] = "中国";

int len = strlen(m_szText)+1;

NPUTF8 *utf8_chars = static_cast<NPUTF8 *>(NPN_MemAlloc(len));

memset( utf8_chars, 0, len );

strncpy( utf8_chars, m_szText, len);

STRINGZ_TO_NPVARIANT(utf8_chars, *result);

因为中文默认是GB2312编码,需要转化成utf8编码,然后返回。
char m_szText[]
= "中国";

int nLen = MultiByteToWideChar(CP_ACP, 0, m_szText, -1, NULL, 0);

if (nLen == 0)

return false;

WCHAR *pwszBuffer = new WCHAR[nLen];

nLen = MultiByteToWideChar(CP_ACP, 0, m_szTextGui, -1, pwszBuffer, nLen);

if (nLen == 0)

return false;

nLen = WideCharToMultiByte(CP_UTF8, 0, pwszBuffer, -1, NULL, 0, NULL, NULL);

if (nLen == 0)

return false;

char *pszBuffer = new char[nLen];

nLen = WideCharToMultiByte(CP_UTF8, 0, pwszBuffer, -1, pszBuffer, nLen, NULL, NULL);

if (nLen == 0)

return false;

nLen = strlen(pszBuffer)+1;

NPUTF8 *utf8_chars = static_cast<NPUTF8 *>(NPN_MemAlloc(nLen));

memset( utf8_chars, 0, nLen );

strncpy( utf8_chars, pszBuffer, nLen);

STRINGZ_TO_NPVARIANT(utf8_chars, *result);

if (pszBuffer)

delete []pszBuffer;

if (pwszBuffer)

delete []pwszBuffer;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: