使用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.
![](http://img.blog.csdn.net/20141011150334918?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2t5bGluMTk4NDAxMDE=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
三、STRINGZ_TO_NPVARIANT与STRINGN_TO_NPVARIANT的区别
把字符串返回给js调用时,NPAPI提供了两个方法,下面先看下他们的定义说明:
Initialize
the value being an
the UTF-8 string value
Initialize
the value being an
the UTF-8 string value
意思都是把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;
如果大家不小心的话,直接使用下面的方式输出
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
vto a variant of type
NPVariantType_Stringwith
the value being an
NPStringholding
the UTF-8 string value
val.
STRINGN_TO_NPVARIANT()
Initialize
vto a variant of type
NPVariantType_Stringwith
the value being an
NPStringholding
the UTF-8 string value
valwith 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;
相关文章推荐
- C# System.DateTime.Now.ToString()使用注意事项
- VFP中set filter to 的使用注意事项
- html to xml:Jtidy的使用及注意事项(jtidy-r938)
- 使用string 的注意事项
- C++学习(五)——string使用注意事项(一)
- hdu 1075 map的使用 字符串截取的常用手段 以及string getline 使用起来的注意事项
- zookeeper使用注意事项 - FAILED TO WRITE PID
- String的类方法使用注意事项
- String 基本使用方法, 以及要注意的事项
- JavaScript toFixed()使用的注意事项
- string convert into dict 字符串转字典避免使用eval的注意事项
- lr_eval_string和lr_save_string 使用注意事项
- CStdioFile::WriteString()使用时的注意事项
- 使用sendmessage发送string的注意事项
- 零碎的小知识点 ----------C# ToString()函数注意事项
- TO_DATE()函数:日期转换时使用RR格式的注意事项
- Linq to SQL Profiler使用注意事项——数据库远程请求
- Linq to SQL Profiler使用注意事项——无限制的结果返回
- cocos2d-x 代码中使用 std::to_string 要注意!
- UITableView使用注意事项(unable to dequeue a cell with identifier)