使用STRINGN_TO_NPVARIANT和STRINGZ_TO_NPVARIANT 注意的事项

一、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_NPVARIANTSTRINGN_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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值