当四字节UTF-8遇上JNI

android在Java层对 utf 编码是支持得很好了,非常全面;但当你从事一些c/c++工程的开发时可就没有这么幸运了。 笔者最近在使用v8 javascript 引擎时便碰到了一个问题:

有些用户在昵称中使用了 emoji 表情,v8 引擎内部默认会使用utf-16编码,通过 v8 API 取到这个值之后转为utf-8的字符串,进而通过 JNI 的 API JNIEnv->NewStringUTF 往 Java 传递时会被系统的 checkJNI 给拦截住而报错。原因在为了让字符串中不包含任何 null 字节,JNI 以及 Java VM 内部都是使用的Modified UTF-8格式来编码字符串。

后来找到一个办法可以通过将字符串转为 utf-16 编码后传递给 JNI API JNIEnv->NewString 解决之:

  1. 使用 v8 API 将 utf-8 的字符串转为 utf-16 编码
    size_t utf8_to_utf16(const char *src, const uint16_t **dest) {
        if (src == NULL || dest == NULL) {
            return 0;
        }
        Isolate::Scope scope(Isolate::GetCurrent());
        HandleScope handle_scope;
        Local<String> str = String::New(src);
        String::Value val(str); // String::Value的内部编码是 utf-16
        const size_t len = (val.length()) * sizeof(uint16_t);
        uint16_t* target = (uint16_t*)calloc(val.length() + 1, sizeof(uint16_t));
        if (target == NULL) {
            return 0;
        }
        memcpy(target, *val, len);
        *dest = target;
        return val.length();
    }
    
  2. 将生成的 utf-16 字符串通过 JNI 传递到 Java 层
    uint16_t *utf16_action = NULL;
    size_t len = utf8_to_utf16(action, &utf16_action);
    jstring jText = (*env)->NewString(env, utf16_action, len);
    if (utf16_action != NULL) {
        free(utf16_action);
    }
    if (len == 0) {
        jText = (*env)->NewStringUTF(env, ""); // 降级到使用NewStringUTF来创建一个""字符串
    }
    

另外一种解决方法是通过 byteArray 来将 utf-8 编码的字符串传送到java层,

时间: 2024-08-18 08:17:51

当四字节UTF-8遇上JNI的相关文章

当 App Store 遇上电视,开发者的第四代 Apple TV 开箱体验

当 App Store 遇上电视,开发者的第四代 Apple TV 开箱体验 引子 2015 年 9 月,San Francisco.今年接近 100 华氏度的气温要比往年都更热,而 Apple 例行的秋季发布会也如期在这里举行.自从 iPhone 一战成名后,每年的 iPhone 旗舰机型都是移动通讯设备的业界标杆.而今年秋季发布会大家也自然地将重点放在了最新的 iPhone 6s 上.手机乏善可陈,除了硬件参数的一些常规升级外,我们并没有看到 iPhone 有多大进步.不过这也是大家预料之中

当搜索引擎营销遇上SaaS(软件即服务)

本文讲的是当搜索引擎营销遇上SaaS(软件即服务),[IT168 资讯]互联网创造若干个神话,也造就无数的网络英雄,随着Web2.0应用的不断深入,销售人员的触脚已经延展到互联网的各个角落,就拿刚刚成立四年的网上提供高端步行和野营装备的Backcountry Edge公司而言,绝对不会放过任何一个营销机会,于是Clickable公司在去年推出新的软件即服务(SaaS)时,该公司马上报名参加测试该服务以求觅得销售良机. Clickable的服务宗旨是在搜索引擎营销的复杂性和乏味性上做减法,让用户能

金融和互联网好像北京遇上西雅图

本文讲的是金融和互联网好像北京遇上西雅图,中国工商银行电子银行部总经理侯本旗表示,金融和互联网好像不太一样,"金融长这样(吴秀波),稳重.可靠.有内涵.互联网长这样,漂亮.任性.烧钱.有魅力.当他们两个遇到一起就变成了这样,被拍成了一部电影<北京遇上西雅图>."他说,未来三年互联网金融势不可当. 以下为演讲实录: 侯本旗:金融和互联网好像不太一样,我不知道大家有没有想过金融长什么样,金融长这样(吴秀波),稳重.可靠.有内涵.互联网长这样(汤唯),漂亮.任性.烧钱.有魅力,当

当技术宅遇上技术债:你见,或者不见 债就在那里

当了15年IT民工,待过几家公司,做过不少项目,捅过一些篓子,也掉进过好多个坑,今天与大家分享一些对于技术债的看法. 大家都知道,我呢,是一个"长情"的人--不知道的话可以用这个关键词加上我的名字搜索一下--. 也就是在一个公司待的年头会长一些,也就有机会用更长的时间视角看待一些系统.项目的发展变化. 对于一些技术债务的产生和影响,以及后续的清偿就有更多的切身体会,最近也比较关注,正好跟大家交流交流. 第一部分:技术债是如何形成的 技术债务是由Ward Cunningham在1992年

当数据智能遇上工业制造

云栖TechDay第32期,阿里云数据业务总架构师周卫天带来主题是"当数据智能遇上工业制造"的演讲.本文主要从DT时代的开启开始谈起,接着分析了智能工业智能化.融合化和人性化的三大趋势,然后着重分享了阿里工业在智能化.融合化和人性化的实践,包括协鑫光伏实践.货运列车智能故障检测和飞机发动机智能健康管理等案例.   以下是精彩内容整理: DT时代用DT实现DT 用DT来实现DT比较有趣,第一个DT代表数据的技术,第二个DT代表数字化的转型.当数据智能碰到工业制造的时候,根据我自己的一些观

curl-messenger 问题提交遇上的编码问题?

问题描述 messenger 问题提交遇上的编码问题? php curl模拟浏览器登录messenger 聊天,发现 要提交类似 "&# 28216;&# 25103;&# 21450;&# 25237;&# 27880;&# 38382;&# 39064;-&# 22312;&# 32447;&# 21672;&# 35810;"这串东西,请问一下这串东西是什么编码? 解决方案 页面提交乱码问题(

imageview-自定义ImageView遇上的无限循环问题

问题描述 自定义ImageView遇上的无限循环问题 我调用setImageBitmap,会出现无限循环知道OOM异常 看下面的什么都没得照样死循环 解决方案 你这死循环了,没有退出机制,不死才怪,本身imgage就是内存大户,你在死循环 解决方案二: 自己调自己当然会挂了 解决方案三: 在setImageBitmap 中调用super.setImageBitmap本身不会造成无限循环, 可能你在createRoundimage方法中调用了setImageBitmap方法,你可以把 create

当设计遇上AI

2017年2月22日云栖TechDay29期,淘宝高级交互设计专家乐乘带来题为"当设计遇上AI"的演讲.本文主要从多维.闭环.在线的设计数据化开始谈起,接着着重分析了设计智能化,包括走过的坑以及设计智能的四个步骤,最后对设计跨界AI进行了分析总结. 伴随着数据的爆发和算法技术的进步,人工智能势必给各行各业带来深远变革.设计这个行业兼具艺术的感性和商业的理性,它与人工智能可以碰撞出什么样的火花呢?下面我们来一起聊聊在阿里电商平台上用人工智能做设计的探索和思考. 以下是精彩分享整理: 阿里

MySQL批量插入遇上唯一索引避免方法_Mysql

一.背景 以前使用SQL Server进行表分区的时候就碰到很多关于唯一索引的问题:Step8:SQL Server 当表分区遇上唯一约束,没想到在MySQL的分区中一样会遇到这样的问题:MySQL表分区实战. 今天我们来了解MySQL唯一索引的一些知识:包括如何创建,如何批量插入,还有一些技巧上SQL: 这些问题的根源在什么地方?有什么共同点?MySQL中也有分区对齐的概念?唯一索引是在很多系统中都会出现的要求,有什么办法可以避免?它对性能的影响有多大? 二.过程 (一) 导入差异数据,忽略重