cef中javascript和c++交换二进制数据(arraybuffer)的方法

javascript的arraybuffer如何传到c++?

javascript可以通过XMLHttpRequest的Get请求得到arraybuffer类型的数据,也可以通过POST请求,向服务器发送arraybuffer数据。
那么利用http请求和cef的custom scheme机制,javascript就可以与本地的c++代码交换arraybuffer数据。

注意:javascript运行在render进程,c++的custom scheme的处理器在browser进程。

基础知识

scheme就是一种协议,比如http://helloworld.com中的http就是scheme,不过它是内置的。
zhangpeng://helloworld.com中的zhangpeng就是一个自定义scheme。
当cef中通过XMLHttpRequest请求地址zhangpeng://helloworld.com时,我们c++中实现的处理器,就会收到这个请求。
但是XMLHttpRequest只支持http/https两种内置的scheme。
所以我们只能定义http、https的自定义scheme handler。

使用http scheme交换arraybuffer

一、cef注册custom scheme 来接收http请求

在cef中我们可以通过以下接口来注册scheme

CefRegisterSchemeHandlerFactory();

注册一个自定义http scheme

CefRegisterSchemeHandlerFactory("http", "zhangpeng", new TestSchemeHandlerFactory());

这个scheme限定了,scheme为"http",domain为"zhangpeng",只有当请求为"http://zhangpeng/"开头时,才会执行自定义c++代码。
处理器工厂为TestSchemeHandlerFactory,是我们自己实现的处理请求的c++代码。

当收到请求时,cef会调用TestSchemeHandlerFactory的Create方法,该方法返回一个TestResourceHandler

CefRefPtr<CefResourceHandler> TestSchemeHandlerFactory::Create(
    CefRefPtr<CefBrowser> browser,
    CefRefPtr<CefFrame> frame,
    const CefString& scheme_name,
    CefRefPtr<CefRequest> request) {
    return new TestResourceHandler();
}

当javascript通过XMLHttpRequest请求地址:http://zhangpeng/ 地址时,我们的c++代码将收到这个请求。

二、使用javascript发送arraybuffer

javascript代码如下:

//假设data是你需要发送的arraybuffer
var url = 'http://zhangpeng/';
var int8View = new window.Uint8Array(data);
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.send(int8View);

三、c++收到arraybuffer数据

C++我们会收到请求,我们可以拿到arraybuffer,这里是browser进程

class TestResourceHandler : public CefResourceHandler {
public:
    virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
        CefRefPtr<CefCallback> callback);
    }
        
bool TestResourceHandler::ProcessRequest(CefRefPtr<CefRequest> request,
    CefRefPtr<CefCallback> callback) {

    CefRefPtr<CefPostData> data_array = request->GetPostData();
    if (data_array->GetElementCount() == 0) {
        return false;
    }
    CefPostData::ElementVector elements;
    data_array->GetElements(elements);

    CefRefPtr<CefPostDataElement> data = elements[0];
    int length = data->GetBytesCount();
    std::vector<uint8_t> v;
    v.resize(length);
    data->GetBytes(length, &v[0]);
    //v里存储了arraybuffer的数据
    return true;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容